Lets do a short introduction to what we’re working with here.
Target Variable
- \(Y\) - Irrigation Percentage - Downloaded the data from Siebert et al. (2015) data set in ha/country/timestep, then by dividing by the countries total area, the fraction of total land area that is irrigated in a given country is created.
#original Siebert Data
aei <- read.csv2("/Volumes/RachelExternal/Thesis/Data/SiebertData/HID_v10/Country_tenyear_ha.csv")
aei <- as.data.frame(aei)
#rename the cols so that I can use them as number
colnames(aei) <- c("country", "ISO", "ID", "1900", "1910","1920","1930","1940","1950","1960","1970","1980","1985","1990","1995","2000","2005")
#tidying data to long format
aei <- pivot_longer(aei,cols = 4:17, names_to = "year", values_to = "aei_ha")
aei$aei_ha <- removePunctuation(aei$aei_ha)
aei$year <- as.numeric(aei$year)
aei$aei_ha <- as.numeric(aei$aei_ha)
aei$ISO <- as.factor(aei$ISO)
aei$country <- as.factor(aei$country)
#subset the data so that its from the year 1960
aei <- aei %>% subset(year >= 1960)
#make a new col for year count
aei$yearcount <- (aei$year - 1960)
#remove data for the total global irrigated area
globeaei <- subset(aei, country == "WORLD")
aei= aei[!aei$country == "WORLD",]
str(aei)
tibble [1,848 × 6] (S3: tbl_df/tbl/data.frame)
$ country : Factor w/ 232 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 2 2 ...
$ ISO : Factor w/ 232 levels "","ABW","AFG",..: 3 3 3 3 3 3 3 3 6 6 ...
$ ID : int [1:1848] 2 2 2 2 2 2 2 2 6 6 ...
$ year : num [1:1848] 1960 1970 1980 1985 1990 ...
$ aei_ha : num [1:1848] 2404990 2408168 2518178 2594394 2903569 ...
$ yearcount: num [1:1848] 0 10 20 25 30 35 40 45 0 10 ...
Added to this to be able to calculate the % of land irrigated per country we need the country area. This data is taken from Worldbank.
#import the data set with total country area, this comes from the Worldbank
countryarea <- read.csv2("/Volumes/RachelExternal/Thesis/Data/LandArea/LandArea.csv")
#removing extra cols
countryarea <- countryarea[-c(265:270), ]
countryarea <- countryarea[, -c(1, 3:4)]
#fix the col names (in the two days since i found this little for loop I learned how to do this faster!)
for ( col in 2:ncol(countryarea)){
colnames(countryarea)[col] <- sub("X", "", colnames(countryarea)[col])
}
remove(col)
#making long data
countryarea <-
countryarea %>%
pivot_longer(!Country.Code, names_to = "year", values_to = "area_km") %>%
rename(ISO = Country.Code)
#fixing variable types
countryarea$ISO <- as.factor(countryarea$ISO)
countryarea$year <- as.numeric(countryarea$year)
str(countryarea)
tibble [16,104 × 3] (S3: tbl_df/tbl/data.frame)
$ ISO : Factor w/ 264 levels "ABW","AFG","AGO",..: 1 1 1 1 1 1 1 1 1 1 ...
$ year : num [1:16104] 1960 1961 1962 1963 1964 ...
$ area_km: num [1:16104] NA 180 180 180 180 180 180 180 180 180 ...
For some reason, the data from Worldbank on each countries area only starts in 1961. For this analysis, 1960 is needed. Country area from 1961 will be substituted for 1960, with the assumption that country area doesn’t change drastically in one year (it doesn’t).
head(subset(countryarea, c(year == 1960 | year == 1961)))
#fixing 1960
countryarea <-
countryarea %>%
group_by(ISO) %>%
fill(area_km, .direction = "up") %>%
ungroup()
Merge the country area with the AEI df here.
#combine these data sets
aei <- aei %>% merge(y = countryarea, by.x = c("ISO", "year"), all.x = TRUE)
rm(countryarea)
head(aei)
Some countries also have no area value. I’ll go through and see if any of the countries with missing area values have non zero AEI_ha. If so, I’ll replace them, as they didn’t come through with the WorldBank data set but are online. Copying and pasting from various sources should be fine.
#checking for countries with NA values in their area_km col
#looking primarily for countries that have non 0 AEI_ha
aei[is.na(aei$area_km),]
#fixing counties with no area
aei$area_km[which(aei$ISO == "GUF")] <- 83534 #French Guiana from Britannica
aei$area_km[which(aei$ISO == "GLP")] <- 1630 #Guadeloupe from Britannica
aei$area_km[which(aei$ISO == "MTQ")] <- 1128 # Martinique from Britannica
aei$area_km[which(aei$ISO == "REU")] <- 2512 #Reunion from Britannica
aei$area_km[which(aei$ISO == "SMK")] <- 13812 + 10905 + 77589 #Montenegro + Kosovo + Serbia from Britannica
aei$area_km[which(aei$ISO == "TWN")] <- 35980 #Taiwan from CIA.gov
aei$area_km[which(aei$ISO == "SDN")] <- 1882000 #Sudan from UNDP
Now, transform the AEI_ha to \(km^2\) and divide to get the % of total country area that is equipped for irrigation. There are still some countries that have 0 AEI_ha and no area_km value. I think I will assign the irrfrac/perc 0 to those countries, but lets wait a little while to do that, most are islands.
aei <- aei %>% mutate(irrperc = ((aei_ha/100)/area_km)*100, irrfrac = ((aei_ha/100)/area_km))
Here is a quick histogram of the target variable. A lot of 0s.
hist(aei$irrperc, breaks = 200)

Chosen Predictor Variables
According to the FAO (Walker 1989), the choice of which irrigation, and by proxy whether to irrigate or not, comes from six factors. The predictor that will be used for this analysis are listed below:
Economic
- \(M_c\) - GDP per Capita - Each country’s GDP per Capita from Gapminder, which collects data from the UN and the Maddison project. This variable will be logged because as stated in Statistical Rethinking (McElreath 2015) McElreath states (pg. 239), “We use the logarithm of it, because the logarithm of GDP is the magnitude of GDP. Since wealth generates wealth, it tends to be exponentially related to anything that increases it”
Topographical
- \(Ru_c\) - Represented here using the “rugged” data set from rethinking, in which a coeff of ruggedness for each country was assigned. This data was taken from Riley, Degloria, and Elliot (1999)
Soil Type
- This will not be included in this analysis. Although, it could be useful there is no good way to quantify soil type on a country level basis. This will be included in the grid cell model, as regions can be easily integrated with the grid cell structure.
Water Supply
- \(R_c\) - Total Precipitation - Translated output from LPJmL. Summed across two dimensions: month and country. In mm/country/year
Crop Type
- Fraction of each crop grown per country - Translated output from LPJmL. Individual crop fraction per grid cell multiplied by respective grid cell area, summed on a country level giving ha of each crop grown per country. This was then divided by total area of the country to achieve the % area occupied by a certain crop per country. Still working out how to work with this predictor.
Social Influences
- \(P_c\) - Total Population - Each country’s total population on a yearly basis. Taken from Gapminder. Again, this will be logged, due to the same argument for GDP, and centered.
All variables will be scaled or centered.
First, the ISO codes and Regions to be able to hold some structure.
#the ISO codes and regional data from Gapminder
iso <- read.csv2("/Volumes/RachelExternal/Thesis/Thesis/Data/GAPminder_ISOcodes.csv")
iso <- iso[, -c(2,7,10,12,13)] #removing extra info
#renaming some cols
iso <-
iso %>%
rename(ISO = GEO, country = name)
#fixing the variable types
iso$ISO <- as.factor(iso$ISO)
iso$country <- as.factor(iso$country)
iso$four_regions <- as.factor(iso$four_regions)
iso$eight_regions <- as.factor(iso$eight_regions)
iso$six_regions <- as.factor(iso$six_regions)
iso$six_regions <- as.factor(iso$six_regions)
iso$World.bank.region <- as.factor(iso$World.bank.region)
str(iso)
'data.frame': 197 obs. of 8 variables:
$ ISO : Factor w/ 197 levels "AFG","AGO","ALB",..: 1 3 50 4 2 8 6 7 9 10 ...
$ country : Factor w/ 197 levels "Afghanistan",..: 1 2 3 4 5 6 7 8 9 10 ...
$ four_regions : Factor w/ 4 levels "africa","americas",..: 3 4 1 4 1 2 2 4 3 4 ...
$ eight_regions : Factor w/ 8 levels "africa_north",..: 5 7 1 8 2 3 4 7 6 8 ...
$ six_regions : Factor w/ 6 levels "america","east_asia_pacific",..: 5 3 4 3 6 1 1 3 2 3 ...
$ Latitude : num 33 41 28 42.5 -12.5 ...
$ Longitude : num 66 20 3 1.52 18.5 ...
$ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: 7 3 5 3 8 4 4 3 2 3 ...
#past me helping future me
#fixing Macedonia, FYR to North Macedonia
iso$country <- as.character(iso$country)
iso[iso == "Macedonia, FYR"] <- "North Macedonia"
iso$country <- as.factor(iso$country)
Cool, we have multiple regions here that we could use in the future for some multilevel business. Also, latitude and longitude is here, which we can also try later. Obviously these lat and lon measurements will mean nothing for a country like China or the USA, but they are nice to have.
Income
Income data is coming from Gapminder, as they have put real effort in to filling all the gaps in income and population for the last 150 years. Income is in terms of the 2011 USD and is inflation adjusted.
#income here is 2011 usd
income <- read.csv("/Volumes/RachelExternal/Thesis/Thesis/Data/Gapminder_income_per_person_gdppercapita_ppp_inflation_adjusted.csv")
income <- income[, c(1, 162:207)] #removing extra years
#making long data
income <-
income %>%
pivot_longer(!country, names_to = "year", values_to = "income")
#still have the xs there
income$year <- str_remove_all(income$year, "[X]")
#transformation of the variable types
income$year <- as.numeric(income$year)
income$country <- as.factor(income$country)
#log and standardize
income$log_income <- log(income$income)
income <- income %>%
mutate(log_income_std = log_income / mean(log_income))
#a summary
summary(income)
country year income
Afghanistan : 46 Min. :1960 Min. : 312
Albania : 46 1st Qu.:1971 1st Qu.: 2250
Algeria : 46 Median :1982 Median : 5290
Andorra : 46 Mean :1982 Mean : 11344
Angola : 46 3rd Qu.:1994 3rd Qu.: 13575
Antigua and Barbuda: 46 Max. :2005 Max. :179000
(Other) :8602
log_income log_income_std
Min. : 5.743 Min. :0.6651
1st Qu.: 7.719 1st Qu.:0.8939
Median : 8.574 Median :0.9929
Mean : 8.635 Mean :1.0000
3rd Qu.: 9.516 3rd Qu.:1.1020
Max. :12.095 Max. :1.4007
#past me helping future me again
#fixing Eswatini to Swaziland (even though Eswatini is the correct name)
income$country <- as.character(income$country)
income[income == "Eswatini"] <- "Swaziland"
income$country <- as.factor(income$country)
Logging and standardizing is necessary here. Again, the argument is that wealth begets wealth, so income is logarithmic. From there just center the mean at 0 with a stdev of 1 for standardization.
Population
Population data is also taken from Gapminder. The same process of logging and standardizing will be carried out here.
#population data also taken from Gapminder
population <- read.csv("/Volumes/RachelExternal/Thesis/Thesis/Data/Gapminder_population_total.csv")
#removing extra years
population <- population[, c(1, 162:207)]
#making longer data
population <-
population %>%
pivot_longer(!country, names_to = "year", values_to = "population")
#removing the Xs from the year strings
population$year <- str_remove_all(population$year, "[X]")
#fixing variable types
population$country <- as.factor(population$country)
population$year <- as.numeric(population$year)
#log and standardize, same argument as income: population begets population
population$log_pop <- log(population$population)
population <- population %>%
mutate(log_pop_std = log_pop / mean(log_pop))
summary(population)
country year
Afghanistan : 46 Min. :1960
Albania : 46 1st Qu.:1971
Algeria : 46 Median :1982
Andorra : 46 Mean :1982
Angola : 46 3rd Qu.:1994
Antigua and Barbuda: 46 Max. :2005
(Other) :8694
population log_pop log_pop_std
Min. :6.450e+02 Min. : 6.469 Min. :0.4316
1st Qu.:9.045e+05 1st Qu.:13.715 1st Qu.:0.9151
Median :4.545e+06 Median :15.330 Median :1.0228
Mean :2.404e+07 Mean :14.988 Mean :1.0000
3rd Qu.:1.320e+07 3rd Qu.:16.396 3rd Qu.:1.0939
Max. :1.330e+09 Max. :21.008 Max. :1.4017
#annnd again...
#fixing Eswatini to Swaziland (even though Eswatini is the correct name)
population$country <- as.character(population$country)
population[population == "Eswatini"] <- "Swaziland"
population$country <- as.factor(population$country)
So some issues arise here with the fact that we have different country data for each dataframe. Sometimes the names are capitalized, other times there are spaces instead of underscores. By using anti_join() I can see what won’t be joined. Also this goes both ways, anti_join() returns rows of x that do not have a match in y.
isopop <- anti_join(iso, population, by = "country")
summary(isopop)
ISO country four_regions
HKG :1 Hong Kong, China:1 africa :0
TWN :1 Taiwan :1 americas:0
AFG :0 Afghanistan :0 asia :2
AGO :0 Albania :0 europe :0
ALB :0 Algeria :0
AND :0 Andorra :0
(Other):0 (Other) :0
eight_regions six_regions
east_asia_pacific :2 america :0
africa_north :0 east_asia_pacific :2
africa_sub_saharan:0 europe_central_asia :0
america_north :0 middle_east_north_africa:0
america_south :0 south_asia :0
asia_west :0 sub_saharan_africa :0
(Other) :0
Latitude Longitude
Min. :22.29 Min. :114.2
1st Qu.:22.71 1st Qu.:115.9
Median :23.14 Median :117.6
Mean :23.14 Mean :117.6
3rd Qu.:23.57 3rd Qu.:119.3
Max. :24.00 Max. :121.0
World.bank.region
East Asia & Pacific :2
:0
Europe & Central Asia :0
Latin America & Caribbean :0
Middle East & North Africa:0
North America :0
(Other) :0
popiso <- anti_join(population, iso, by = "country")
summary(popiso)
country year population
Afghanistan :0 Min. : NA Min. : NA
Albania :0 1st Qu.: NA 1st Qu.: NA
Algeria :0 Median : NA Median : NA
Andorra :0 Mean :NaN Mean :NaN
Angola :0 3rd Qu.: NA 3rd Qu.: NA
Antigua and Barbuda:0 Max. : NA Max. : NA
(Other) :0
log_pop log_pop_std
Min. : NA Min. : NA
1st Qu.: NA 1st Qu.: NA
Median : NA Median : NA
Mean :NaN Mean :NaN
3rd Qu.: NA 3rd Qu.: NA
Max. : NA Max. : NA
Went back up and solved the issue of North Macedonia and Swaziland. There are still issues with Hong Kong and Taiwan as they are part of China. ISO has data for Hong Kong and Taiwan that population does not have. I wont include them in the HTML but they are in the code.
Alright, so I will left join ISO and population then again with income? Not sure that this will solve my problem, but lets try it.
#remove all these rando tables
rm(popinc, inciso, incpop, popiso, isoinc, isopop)
#
iso <- left_join(iso, population, by = "country")
iso <- left_join(iso, income, by = c("country", "year"))
# alright 197 countries! whoop!
str(iso)
'data.frame': 8972 obs. of 15 variables:
$ ISO : Factor w/ 197 levels "AFG","AGO","ALB",..: 1 1 1 1 1 1 1 1 1 1 ...
$ country : Factor w/ 197 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
$ four_regions : Factor w/ 4 levels "africa","americas",..: 3 3 3 3 3 3 3 3 3 3 ...
$ eight_regions : Factor w/ 8 levels "africa_north",..: 5 5 5 5 5 5 5 5 5 5 ...
$ six_regions : Factor w/ 6 levels "america","east_asia_pacific",..: 5 5 5 5 5 5 5 5 5 5 ...
$ Latitude : num 33 33 33 33 33 33 33 33 33 33 ...
$ Longitude : num 66 66 66 66 66 66 66 66 66 66 ...
$ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: 7 7 7 7 7 7 7 7 7 7 ...
$ year : num 1960 1961 1962 1963 1964 ...
$ population : int 9000000 9170000 9350000 9540000 9740000 9960000 10200000 10400000 10600000 10900000 ...
$ log_pop : num 16 16 16.1 16.1 16.1 ...
$ log_pop_std : num 1.07 1.07 1.07 1.07 1.07 ...
$ income : int 2740 2700 2680 2670 2650 2640 2600 2600 2620 2590 ...
$ log_income : num 7.92 7.9 7.89 7.89 7.88 ...
$ log_income_std : num 0.917 0.915 0.914 0.914 0.913 ...
rm(income, population)
Now, join ISO to AEI with a merge (cause in this case the dynamics of merge are clearer for me). Hoping to preserve all data!
aei <- merge(aei, iso, by = c("ISO","country", "year"), all.x = TRUE)
rm(iso)
str(aei)
'data.frame': 1848 obs. of 21 variables:
$ ISO : Factor w/ 232 levels "","ABW","AFG",..: 2 2 2 2 2 2 2 2 3 3 ...
$ country : Factor w/ 232 levels "Afghanistan",..: 12 12 12 12 12 12 12 12 1 1 ...
$ year : num 1960 1970 1980 1985 1990 ...
$ ID : int 1 1 1 1 1 1 1 1 2 2 ...
$ aei_ha : num 0 0 0 0 0 ...
$ yearcount : num 0 10 20 25 30 35 40 45 0 10 ...
$ area_km : num 180 180 180 180 180 ...
$ irrperc : num 0 0 0 0 0 ...
$ irrfrac : num 0 0 0 0 0 ...
$ four_regions : Factor w/ 4 levels "africa","americas",..: NA NA NA NA NA NA NA NA 3 3 ...
$ eight_regions : Factor w/ 8 levels "africa_north",..: NA NA NA NA NA NA NA NA 5 5 ...
$ six_regions : Factor w/ 6 levels "america","east_asia_pacific",..: NA NA NA NA NA NA NA NA 5 5 ...
$ Latitude : num NA NA NA NA NA NA NA NA 33 33 ...
$ Longitude : num NA NA NA NA NA NA NA NA 66 66 ...
$ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: NA NA NA NA NA NA NA NA 7 7 ...
$ population : int NA NA NA NA NA NA NA NA 9000000 11200000 ...
$ log_pop : num NA NA NA NA NA ...
$ log_pop_std : num NA NA NA NA NA ...
$ income : int NA NA NA NA NA NA NA NA 2740 2570 ...
$ log_income : num NA NA NA NA NA ...
$ log_income_std : num NA NA NA NA NA ...
Solved the issue, 232 factors for both countries and ISO, meaning that we have been using the original AEI file from Siebert as the main data frame to join to. Good. This is the data that needs to be maintained, NAs can pop up in other cols but not irrigated area.
But I still would like total GDP for later so lets transform using population.
aei$income <- as.numeric(aei$income)
#mutating for total GDP and log GDP
aei <-
aei %>%
mutate(GDPtot = income*population) %>%
mutate(log_gdp_tot = log(GDPtot))
#creating the df to standardize without the NAs
aei2 <-
aei %>%
select(ISO, year, log_gdp_tot) %>%
na.omit() %>%
mutate(log_gdp_tot_std = log_gdp_tot/mean(log_gdp_tot)) %>%
select(ISO, year, log_gdp_tot_std)
#now rejoin!
aei <-
left_join(aei, aei2, by = c("ISO", "year"))
str(aei)
'data.frame': 1848 obs. of 24 variables:
$ ISO : Factor w/ 232 levels "","ABW","AFG",..: 2 2 2 2 2 2 2 2 3 3 ...
$ country : Factor w/ 232 levels "Afghanistan",..: 12 12 12 12 12 12 12 12 1 1 ...
$ year : num 1960 1970 1980 1985 1990 ...
$ ID : int 1 1 1 1 1 1 1 1 2 2 ...
$ aei_ha : num 0 0 0 0 0 ...
$ yearcount : num 0 10 20 25 30 35 40 45 0 10 ...
$ area_km : num 180 180 180 180 180 ...
$ irrperc : num 0 0 0 0 0 ...
$ irrfrac : num 0 0 0 0 0 ...
$ four_regions : Factor w/ 4 levels "africa","americas",..: NA NA NA NA NA NA NA NA 3 3 ...
$ eight_regions : Factor w/ 8 levels "africa_north",..: NA NA NA NA NA NA NA NA 5 5 ...
$ six_regions : Factor w/ 6 levels "america","east_asia_pacific",..: NA NA NA NA NA NA NA NA 5 5 ...
$ Latitude : num NA NA NA NA NA NA NA NA 33 33 ...
$ Longitude : num NA NA NA NA NA NA NA NA 66 66 ...
$ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: NA NA NA NA NA NA NA NA 7 7 ...
$ population : int NA NA NA NA NA NA NA NA 9000000 11200000 ...
$ log_pop : num NA NA NA NA NA ...
$ log_pop_std : num NA NA NA NA NA ...
$ income : num NA NA NA NA NA NA NA NA 2740 2570 ...
$ log_income : num NA NA NA NA NA ...
$ log_income_std : num NA NA NA NA NA ...
$ GDPtot : num NA NA NA NA NA ...
$ log_gdp_tot : num NA NA NA NA NA ...
$ log_gdp_tot_std : num NA NA NA NA NA ...
Finally, lets check out a quick histogram of GDP and pop,
hist(aei$log_gdp_tot_std, breaks = 100)

hist(aei$log_pop_std, breaks = 100)

Dealing with Some Issues
There are a lot of countries that have no data for the regions, but have non zero irrperc/frac which I will use in further analysis, so we need to replace the regions.
#view which countries don't have regions but have non zero irrprec
na_regions <- aei[is.na(aei$four_regions),]
#Aruba
aei <- aei %>%
mutate(four_regions = replace(four_regions, ISO == 'ABW', 'americas'),
six_regions = replace(six_regions, ISO == 'ABW', 'america'),
eight_regions = replace(eight_regions, ISO == 'ABW', 'america_north')) %>%
#american samoa
mutate(four_regions = replace(four_regions,ISO == 'ASM', 'asia'),
six_regions = replace(six_regions,ISO == 'ASM', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'ASM', 'east_asia_pacific')) %>%
#bermuda
mutate(four_regions = replace(four_regions,ISO == 'BMU', 'americas'),
six_regions = replace(six_regions,ISO == 'BMU', 'america'),
eight_regions = replace(eight_regions,ISO == 'BMU', 'america_north')) %>%
#cote d'ivoire
mutate(four_regions = replace(four_regions,ISO == 'CIV', 'africa'),
six_regions = replace(six_regions,ISO == 'CIV', 'sub_saharan_africa'),
eight_regions = replace(eight_regions,ISO == 'CIV', 'africa_sub_saharan')) %>%
#democratic republic of congo
mutate(four_regions = replace(four_regions,ISO == 'COD', 'africa'),
six_regions = replace(six_regions,ISO == 'COD', 'sub_saharan_africa'),
eight_regions = replace(eight_regions,ISO == 'COD', 'africa_sub_saharan')) %>%
#republic of congo
mutate(four_regions = replace(four_regions,ISO == 'COG', 'africa'),
six_regions = replace(six_regions,ISO == 'COG', 'sub_saharan_africa'),
eight_regions = replace(eight_regions,ISO == 'COG', 'africa_sub_saharan')) %>%
#cayman islands
mutate(four_regions = replace(four_regions,ISO == 'CYM', 'americas'),
six_regions = replace(six_regions,ISO == 'CYM', 'america'),
eight_regions = replace(eight_regions,ISO == 'CYM', 'america_north')) %>%
#Faroe islands
mutate(four_regions = replace(four_regions,ISO == 'FRO', 'europe'),
six_regions = replace(six_regions,ISO == 'FRO', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'FRO', 'europe_west')) %>%
#micronesia
mutate(four_regions = replace(four_regions,ISO == 'FSM', 'asia'),
six_regions = replace(six_regions,ISO == 'FSM', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'FSM', 'east_asia_pacific')) %>%
#gibraltar
mutate(four_regions = replace(four_regions,ISO == 'GIB', 'europe'),
six_regions = replace(six_regions,ISO == 'GIB', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'GIB', 'europe_west')) %>%
#Guadeloupe
mutate(four_regions = replace(four_regions,ISO == 'GLP', 'americas'),
six_regions = replace(six_regions,ISO == 'GLP', 'america'),
eight_regions = replace(eight_regions,ISO == 'GLP', 'america_north')) %>%
#greenland
mutate(four_regions = replace(four_regions,ISO == 'GRL', 'europe'),
six_regions = replace(six_regions,ISO == 'GRL', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'GRL', 'europe_west')) %>%
#french Guiana
mutate(four_regions = replace(four_regions,ISO == 'GUF', 'americas'),
six_regions = replace(six_regions,ISO == 'GUF', 'america'),
eight_regions = replace(eight_regions,ISO == 'GUF', 'america_south')) %>%
#guam
mutate(four_regions = replace(four_regions,ISO == 'GUM', 'asia'),
six_regions = replace(six_regions,ISO == 'GUM', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'GUM', 'east_asia_pacific')) %>%
#Kyrgyzstan
mutate(four_regions = replace(four_regions,ISO == 'KGZ', 'asia'),
six_regions = replace(six_regions,ISO == 'KGZ', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'KGZ', 'asia_west')) %>%
#laos
mutate(four_regions = replace(four_regions,ISO == 'LAO', 'asia'),
six_regions = replace(six_regions,ISO == 'LAO', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'LAO', 'east_asia_pacific')) %>%
#Macedonia
mutate(four_regions = replace(four_regions,ISO == 'MKD', 'europe'),
six_regions = replace(six_regions,ISO == 'MKD', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'MKD', 'europe_east')) %>%
#Martinique
mutate(four_regions = replace(four_regions,ISO == 'MTQ', 'americas'),
six_regions = replace(six_regions,ISO == 'MTQ', 'america'),
eight_regions = replace(eight_regions,ISO == 'MTQ', 'america_north')) %>%
#new caledonia
mutate(four_regions = replace(four_regions,ISO == 'NCL', 'asia'),
six_regions = replace(six_regions,ISO == 'NCL', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'NCL', 'east_asia_pacific')) %>%
#puerto rico
mutate(four_regions = replace(four_regions,ISO == 'PRI', 'americas'),
six_regions = replace(six_regions,ISO == 'PRI', 'america'),
eight_regions = replace(eight_regions,ISO == 'PRI', 'america_north')) %>%
#Palestine (West Bank + Gaza strip)
mutate(four_regions = replace(four_regions,ISO == 'PSE', 'asia'),
six_regions = replace(six_regions,ISO == 'PSE', 'middle_east_north_africa'),
eight_regions = replace(eight_regions,ISO == 'PSE', 'asia_west')) %>%
#french Polynesia
mutate(four_regions = replace(four_regions,ISO == 'PYF', 'asia'),
six_regions = replace(six_regions,ISO == 'PYF', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'PYF', 'east_asia_pacific')) %>%
#Reunion
mutate(four_regions = replace(four_regions,ISO == 'REU', 'africa'),
six_regions = replace(six_regions,ISO == 'REU', 'sub_saharan_africa'),
eight_regions = replace(eight_regions,ISO == 'REU', 'africa_sub_saharan')) %>%
#Serbia, Montenegro, Kosovo
mutate(four_regions = replace(four_regions,ISO == 'SMK', 'europe'),
six_regions = replace(six_regions,ISO == 'SMK', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'SMK', 'europe_east')) %>%
#Slovakia
mutate(four_regions = replace(four_regions,ISO == 'SVK', 'europe'),
six_regions = replace(six_regions,ISO == 'SVK', 'europe_central_asia'),
eight_regions = replace(eight_regions,ISO == 'SVK', 'europe_east')) %>%
#Turks and Caicos Islands
mutate(four_regions = replace(four_regions,ISO == 'TCA', 'americas'),
six_regions = replace(six_regions,ISO == 'TCA', 'america'),
eight_regions = replace(eight_regions,ISO == 'TCA', 'america_north')) %>%
#East Timor
mutate(four_regions = replace(four_regions,ISO == 'TLS', 'asia'),
six_regions = replace(six_regions,ISO == 'TLS', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'TLS', 'east_asia_pacific')) %>%
#taiwan
mutate(four_regions = replace(four_regions,ISO == 'TWN', 'asia'),
six_regions = replace(six_regions,ISO == 'TWN', 'east_asia_pacific'),
eight_regions = replace(eight_regions,ISO == 'TWN', 'east_asia_pacific')) %>%
#British virgin Islands
mutate(four_regions = replace(four_regions,ISO == 'VGB', 'americas'),
six_regions = replace(six_regions,ISO == 'VGB', 'america'),
eight_regions = replace(eight_regions,ISO == 'VGB', 'america_north')) %>%
#US Virgin Islands
mutate(four_regions = replace(four_regions,ISO == 'VIR', 'americas'),
six_regions = replace(six_regions,ISO == 'VIR', 'america'),
eight_regions = replace(eight_regions, ISO == 'VIR', 'america_north'))
Next time I’ll write a function.
There are also a lot of countries that have NA values for their income or population. Take a peek here.
lotanas <- aei[rowSums(is.na(aei)) > 0,]
lotanas %>%
group_by(country) %>%
select(income, population) %>%
summarise_all(funs(sum(is.na(.))))
NA
NA
The countries that don’t have income also don’t have population, so as least I am consistent in my missing data. I have to move on so I will just leave this here for a minute. Perhaps later we should fill these variables.
Precipitation
Again, precipitation is translated output from LPJmL. Precipitation was chosen because it could be summed across countries, as other data could not (like discharge or ET). I have summed the precipitation by country and year. I am not sure whether I should scale or standardize precip, I will do all the possible combinations at the moment.
#precipitation
#cftandprecip is a script with all the grid cell values.
cftandprecip <- read.csv('/Volumes/RachelExternal/Thesis/Thesis/Data/cft_and_precipdata.csv')
cftandprecip$ISO <- as.factor(cftandprecip$ISO)
cftandprecip <- cftandprecip[, -c(1)] #remove id col
cftandprecip <- subset(cftandprecip, year >= 1960)
#log and scale
precip <-
cftandprecip %>%
select(ISO, year, precipmm) %>%
group_by(ISO, year) %>%
summarise(preciptot = (sum(precipmm))) %>% #sum grid cells by ISO and year
mutate(precip_sc = preciptot/max(preciptot)) %>%
mutate(precip_std = preciptot/mean(preciptot)) %>%
mutate(log_precip = log(preciptot+1)) %>% #1 is added here to prevent -Inf
mutate(log_precip_sc = log_precip/max(log_precip)) %>%
mutate(log_precip_std = log_precip/mean(log_precip))
#merge
aei <- merge(aei, precip, by = c("ISO", "year"), all.x = TRUE)
rm(precip)
And some histograms to check out the scaled/standardized data.
hist(aei$preciptot, breaks = 100)

hist(aei$precip_sc, breaks = 100)

hist(aei$precip_std, breaks = 100)

hist(aei$log_precip, breaks = 100)

hist(aei$log_precip_sc, breaks = 100)

hist(aei$log_precip_std, breaks = 100)

Crop Fraction
Uff. Then comes crop fraction. As mentioned above individual crop fraction per grid cell is multiplied by respective grid cell area, summed on a country level giving ha of each crop grown per country. This was then divided by total area of the country to achieve the % area occupied by a certain crop per country.
#pull cft frac outta here
cft <-
cftandprecip %>%
select(-c(4)) %>% #removing precip
mutate_each(funs(.*cellaream2), c(4:35)) %>% #multiply all fractions with the cell area
group_by(ISO, year) %>% #group in to country and year
summarise_each(funs(sum)) %>% #take col sums for each crop
mutate(across(c(3:34), .fns = ~./cellaream2)) #divide col sums by total country area
#removing categories with 0 (the biofuels and such)
cft <- cft[, -c(18, 19, 26, 34, 35)]
#and a merge
aei <- merge(aei, cft, by = c("ISO", "year"), all.x = TRUE)
rm(cft, cftandprecip)
Idk how to show the data here. Any ideas on representation would be helpful here.
Topographical
Topographical data is represented here by the data set from Riley, Degloria, and Elliot (1999) and is conviently available through the library(rethinking) from McElreath (2015). It provides a ruggedness factor for each country.
#rugged
data("rugged")
rug <- rugged %>% select(c("isocode", "rugged"))
colnames(rug) <- c("ISO", "rugged")
#scaling
rug$rugged_sc <- rug$rugged / max(rug$rugged)
#merge
aei <- merge(aei, rug, by = "ISO", all.x = TRUE)
rm(rug, rugged)
hist(aei$rugged_sc, breaks = 100)

LS0tCnRpdGxlOiAiMiBDb3VudHJ5IExldmVsIERhdGEgQ2xlYW5pbmciCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICB0b2M6IHllcwogIHRvY19mbG9hdDogeWVzCmJpYmxpb2dyYXBoeTogL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9iaWIuYmliCi0tLQoKYGBge3IgSG91c2VrZWVwaW5nLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGJybXMpCmxpYnJhcnkocnN0YW4pCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocmV0aGlua2luZykKbGlicmFyeShwdXJycikKbGlicmFyeShnZ2FuaW1hdGUpCmxpYnJhcnkod2JzdGF0cykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHRtKQpsaWJyYXJ5KHdic3RhdHMpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoZGlzdGlsbCkKYGBgCgoKCkxldHMgZG8gYSBzaG9ydCBpbnRyb2R1Y3Rpb24gdG8gd2hhdCB3ZSdyZSB3b3JraW5nIHdpdGggaGVyZS4gCgojIFRhcmdldCBWYXJpYWJsZSAgCiAgCiogJFkkIC0gSXJyaWdhdGlvbiBQZXJjZW50YWdlIC0gRG93bmxvYWRlZCB0aGUgZGF0YSBmcm9tIEBzaWViZXJ0R2xvYmFsRGF0YVNldDIwMTUgZGF0YSBzZXQgaW4gaGEvY291bnRyeS90aW1lc3RlcCwgdGhlbiBieSBkaXZpZGluZyBieSB0aGUgY291bnRyaWVzIHRvdGFsIGFyZWEsIHRoZSBmcmFjdGlvbiBvZiB0b3RhbCBsYW5kIGFyZWEgdGhhdCBpcyBpcnJpZ2F0ZWQgaW4gYSBnaXZlbiBjb3VudHJ5IGlzIGNyZWF0ZWQuIApgYGB7ciBTZXR0aW5nIHVwIENvdW50cnkgTGV2ZWwgZGYsIHdhcm5pbmc9RkFMU0V9CiNvcmlnaW5hbCBTaWViZXJ0IERhdGEKYWVpIDwtIHJlYWQuY3N2MigiL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL0RhdGEvU2llYmVydERhdGEvSElEX3YxMC9Db3VudHJ5X3RlbnllYXJfaGEuY3N2IikKYWVpIDwtIGFzLmRhdGEuZnJhbWUoYWVpKQoKI3JlbmFtZSB0aGUgY29scyBzbyB0aGF0IEkgY2FuIHVzZSB0aGVtIGFzIG51bWJlcgpjb2xuYW1lcyhhZWkpIDwtIGMoImNvdW50cnkiLCAiSVNPIiwgIklEIiwgIjE5MDAiLCAiMTkxMCIsIjE5MjAiLCIxOTMwIiwiMTk0MCIsIjE5NTAiLCIxOTYwIiwiMTk3MCIsIjE5ODAiLCIxOTg1IiwiMTk5MCIsIjE5OTUiLCIyMDAwIiwiMjAwNSIpCgojdGlkeWluZyBkYXRhIHRvIGxvbmcgZm9ybWF0CmFlaSA8LSBwaXZvdF9sb25nZXIoYWVpLGNvbHMgPSA0OjE3LCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImFlaV9oYSIpCmFlaSRhZWlfaGEgPC0gcmVtb3ZlUHVuY3R1YXRpb24oYWVpJGFlaV9oYSkKYWVpJHllYXIgPC0gYXMubnVtZXJpYyhhZWkkeWVhcikKYWVpJGFlaV9oYSA8LSBhcy5udW1lcmljKGFlaSRhZWlfaGEpCmFlaSRJU08gPC0gYXMuZmFjdG9yKGFlaSRJU08pCmFlaSRjb3VudHJ5IDwtIGFzLmZhY3RvcihhZWkkY291bnRyeSkKI3N1YnNldCB0aGUgZGF0YSBzbyB0aGF0IGl0cyBmcm9tIHRoZSB5ZWFyIDE5NjAKYWVpIDwtIGFlaSAlPiUgc3Vic2V0KHllYXIgPj0gMTk2MCkKCiNtYWtlIGEgbmV3IGNvbCBmb3IgeWVhciBjb3VudAphZWkkeWVhcmNvdW50IDwtIChhZWkkeWVhciAtIDE5NjApCgojcmVtb3ZlIGRhdGEgZm9yIHRoZSB0b3RhbCBnbG9iYWwgaXJyaWdhdGVkIGFyZWEKZ2xvYmVhZWkgPC0gc3Vic2V0KGFlaSwgY291bnRyeSA9PSAiV09STEQiKQphZWk9IGFlaVshYWVpJGNvdW50cnkgPT0gIldPUkxEIixdCgpzdHIoYWVpKQpgYGAKCiAgICAgIApBZGRlZCB0byB0aGlzIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHRoZSAlIG9mIGxhbmQgaXJyaWdhdGVkIHBlciBjb3VudHJ5IHdlIG5lZWQgdGhlIGNvdW50cnkgYXJlYS4gVGhpcyBkYXRhIGlzIHRha2VuIGZyb20gV29ybGRiYW5rLiAgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW1wb3J0IHRoZSBkYXRhIHNldCB3aXRoIHRvdGFsIGNvdW50cnkgYXJlYSwgdGhpcyBjb21lcyBmcm9tIHRoZSBXb3JsZGJhbmsKY291bnRyeWFyZWEgPC0gcmVhZC5jc3YyKCIvVm9sdW1lcy9SYWNoZWxFeHRlcm5hbC9UaGVzaXMvRGF0YS9MYW5kQXJlYS9MYW5kQXJlYS5jc3YiKQoKI3JlbW92aW5nIGV4dHJhIGNvbHMKY291bnRyeWFyZWEgPC0gY291bnRyeWFyZWFbLWMoMjY1OjI3MCksIF0KY291bnRyeWFyZWEgPC0gY291bnRyeWFyZWFbLCAtYygxLCAzOjQpXQoKI2ZpeCB0aGUgY29sIG5hbWVzIChpbiB0aGUgdHdvIGRheXMgc2luY2UgaSBmb3VuZCB0aGlzIGxpdHRsZSBmb3IgbG9vcCBJIGxlYXJuZWQgaG93IHRvIGRvIHRoaXMgZmFzdGVyISkKZm9yICggY29sIGluIDI6bmNvbChjb3VudHJ5YXJlYSkpewogICAgY29sbmFtZXMoY291bnRyeWFyZWEpW2NvbF0gPC0gIHN1YigiWCIsICIiLCBjb2xuYW1lcyhjb3VudHJ5YXJlYSlbY29sXSkKfQpyZW1vdmUoY29sKQoKI21ha2luZyBsb25nIGRhdGEKY291bnRyeWFyZWEgPC0gCiAgY291bnRyeWFyZWEgJT4lICAKICBwaXZvdF9sb25nZXIoIUNvdW50cnkuQ29kZSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJhcmVhX2ttIikgJT4lIAogIHJlbmFtZShJU08gPSBDb3VudHJ5LkNvZGUpCgojZml4aW5nIHZhcmlhYmxlIHR5cGVzCmNvdW50cnlhcmVhJElTTyA8LSBhcy5mYWN0b3IoY291bnRyeWFyZWEkSVNPKQpjb3VudHJ5YXJlYSR5ZWFyIDwtIGFzLm51bWVyaWMoY291bnRyeWFyZWEkeWVhcikKc3RyKGNvdW50cnlhcmVhKQpgYGAKCgpGb3Igc29tZSByZWFzb24sIHRoZSBkYXRhIGZyb20gV29ybGRiYW5rIG9uIGVhY2ggY291bnRyaWVzIGFyZWEgb25seSBzdGFydHMgaW4gMTk2MS4gRm9yIHRoaXMgYW5hbHlzaXMsIDE5NjAgaXMgbmVlZGVkLiBDb3VudHJ5IGFyZWEgZnJvbSAxOTYxIHdpbGwgYmUgc3Vic3RpdHV0ZWQgZm9yIDE5NjAsIHdpdGggdGhlIGFzc3VtcHRpb24gdGhhdCBjb3VudHJ5IGFyZWEgZG9lc24ndCBjaGFuZ2UgZHJhc3RpY2FsbHkgaW4gb25lIHllYXIgKGl0IGRvZXNuJ3QpLiAgCgpgYGB7ciB3YXJuaW5nID0gRkFMU0V9CmhlYWQoc3Vic2V0KGNvdW50cnlhcmVhLCBjKHllYXIgPT0gMTk2MCB8IHllYXIgPT0gMTk2MSkpKSAKCiNmaXhpbmcgMTk2MApjb3VudHJ5YXJlYSA8LQogIGNvdW50cnlhcmVhICU+JSAKICBncm91cF9ieShJU08pICU+JSAKICBmaWxsKGFyZWFfa20sIC5kaXJlY3Rpb24gPSAidXAiKSAlPiUgCiAgdW5ncm91cCgpCgpgYGAKCk1lcmdlIHRoZSBjb3VudHJ5IGFyZWEgd2l0aCB0aGUgQUVJIGRmIGhlcmUuICAgCgpgYGB7ciBKb2luIENBciB9CiNjb21iaW5lIHRoZXNlIGRhdGEgc2V0cwphZWkgPC0gYWVpICU+JSBtZXJnZSh5ID0gY291bnRyeWFyZWEsIGJ5LnggPSBjKCJJU08iLCAieWVhciIpLCBhbGwueCA9IFRSVUUpCgpybShjb3VudHJ5YXJlYSkKaGVhZChhZWkpCmBgYAoKU29tZSBjb3VudHJpZXMgYWxzbyBoYXZlIG5vIGFyZWEgdmFsdWUuIEknbGwgZ28gdGhyb3VnaCBhbmQgc2VlIGlmIGFueSBvZiB0aGUgY291bnRyaWVzIHdpdGggbWlzc2luZyBhcmVhIHZhbHVlcyBoYXZlIG5vbiB6ZXJvIEFFSV9oYS4gSWYgc28sIEknbGwgcmVwbGFjZSB0aGVtLCBhcyB0aGV5IGRpZG4ndCBjb21lIHRocm91Z2ggd2l0aCB0aGUgV29ybGRCYW5rIGRhdGEgc2V0IGJ1dCBhcmUgb25saW5lLiBDb3B5aW5nIGFuZCBwYXN0aW5nIGZyb20gdmFyaW91cyBzb3VyY2VzIHNob3VsZCBiZSBmaW5lLgoKCmBgYHtyIEZpeGVzIGZvciBDQXJ9CiNjaGVja2luZyBmb3IgY291bnRyaWVzIHdpdGggTkEgdmFsdWVzIGluIHRoZWlyIGFyZWFfa20gY29sCiNsb29raW5nIHByaW1hcmlseSBmb3IgY291bnRyaWVzIHRoYXQgaGF2ZSBub24gMCBBRUlfaGEKYWVpW2lzLm5hKGFlaSRhcmVhX2ttKSxdCiAgICAgICAgICAgICAgICAKI2ZpeGluZyBjb3VudGllcyB3aXRoIG5vIGFyZWEKYWVpJGFyZWFfa21bd2hpY2goYWVpJElTTyA9PSAiR1VGIildIDwtIDgzNTM0ICNGcmVuY2ggR3VpYW5hIGZyb20gQnJpdGFubmljYQphZWkkYXJlYV9rbVt3aGljaChhZWkkSVNPID09ICJHTFAiKV0gPC0gMTYzMCAjR3VhZGVsb3VwZSBmcm9tIEJyaXRhbm5pY2EgCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIk1UUSIpXSA8LSAxMTI4ICMgTWFydGluaXF1ZSBmcm9tIEJyaXRhbm5pY2EKYWVpJGFyZWFfa21bd2hpY2goYWVpJElTTyA9PSAiUkVVIildIDwtIDI1MTIgI1JldW5pb24gZnJvbSBCcml0YW5uaWNhCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIlNNSyIpXSA8LSAxMzgxMiArIDEwOTA1ICsgNzc1ODkgI01vbnRlbmVncm8gKyBLb3Nvdm8gKyBTZXJiaWEgZnJvbSBCcml0YW5uaWNhCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIlRXTiIpXSA8LSAzNTk4MCAjVGFpd2FuIGZyb20gQ0lBLmdvdgphZWkkYXJlYV9rbVt3aGljaChhZWkkSVNPID09ICJTRE4iKV0gPC0gMTg4MjAwMCAjU3VkYW4gZnJvbSBVTkRQCmBgYAoKCk5vdywgdHJhbnNmb3JtIHRoZSBBRUlfaGEgdG8gJGttXjIkIGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSAlIG9mIHRvdGFsIGNvdW50cnkgYXJlYSB0aGF0IGlzIGVxdWlwcGVkIGZvciBpcnJpZ2F0aW9uLiBUaGVyZSBhcmUgc3RpbGwgc29tZSBjb3VudHJpZXMgdGhhdCBoYXZlIDAgQUVJX2hhIGFuZCBubyBhcmVhX2ttIHZhbHVlLiBJIHRoaW5rIEkgd2lsbCBhc3NpZ24gdGhlIGlycmZyYWMvcGVyYyAwIHRvIHRob3NlIGNvdW50cmllcywgYnV0IGxldHMgd2FpdCBhIGxpdHRsZSB3aGlsZSB0byBkbyB0aGF0LCBtb3N0IGFyZSBpc2xhbmRzLiAgCgpgYGB7ciBDcmVhdGluZyBUYXJnZXQgVmFyaWFibGV9CmFlaSA8LSBhZWkgJT4lIG11dGF0ZShpcnJwZXJjID0gKChhZWlfaGEvMTAwKS9hcmVhX2ttKSoxMDAsIGlycmZyYWMgPSAoKGFlaV9oYS8xMDApL2FyZWFfa20pKQpgYGAKCkhlcmUgaXMgYSBxdWljayBoaXN0b2dyYW0gb2YgdGhlIHRhcmdldCB2YXJpYWJsZS4gQSBsb3Qgb2YgMHMuIAoKYGBge3IgSGlzdCBvZiBUVmFyfQpoaXN0KGFlaSRpcnJwZXJjLCBicmVha3MgPSAyMDApCmBgYAoKKioqCgojIENob3NlbiBQcmVkaWN0b3IgVmFyaWFibGVzICAKCkFjY29yZGluZyB0byB0aGUgRkFPIFtAd2Fsa2VyRkFPSXJyaWdhdGlvbkRyYWluYWdlMTk4OV0sIHRoZSBjaG9pY2Ugb2Ygd2hpY2ggaXJyaWdhdGlvbiwgYW5kIGJ5IHByb3h5IHdoZXRoZXIgdG8gaXJyaWdhdGUgb3Igbm90LCBjb21lcyBmcm9tIHNpeCBmYWN0b3JzLiBUaGUgcHJlZGljdG9yIHRoYXQgd2lsbCBiZSB1c2VkIGZvciB0aGlzIGFuYWx5c2lzIGFyZSBsaXN0ZWQgYmVsb3c6ICAKCi0gRWNvbm9taWMgCgogIC0gJE1fYyQgLSBHRFAgcGVyIENhcGl0YSAtIEVhY2ggY291bnRyeSdzIEdEUCBwZXIgQ2FwaXRhIGZyb20gR2FwbWluZGVyLCB3aGljaCBjb2xsZWN0cyBkYXRhIGZyb20gdGhlIFVOIGFuZCB0aGUgTWFkZGlzb24gcHJvamVjdC4gVGhpcyB2YXJpYWJsZSB3aWxsIGJlIGxvZ2dlZCBiZWNhdXNlIGFzIHN0YXRlZCBpbiAqU3RhdGlzdGljYWwgUmV0aGlua2luZyogW0BtY2VscmVhdGhTdGF0aXN0aWNhbFJldGhpbmtpbmdCYXllc2lhbjIwMTVdIE1jRWxyZWF0aCBzdGF0ZXMgKHBnLiAyMzkpLCAiV2UgdXNlIHRoZSBsb2dhcml0aG0gb2YgaXQsIGJlY2F1c2UgdGhlIGxvZ2FyaXRobSBvZiBHRFAgaXMgdGhlICptYWduaXR1ZGUqIG9mIEdEUC4gU2luY2Ugd2VhbHRoIGdlbmVyYXRlcyB3ZWFsdGgsIGl0IHRlbmRzIHRvIGJlIGV4cG9uZW50aWFsbHkgcmVsYXRlZCB0byBhbnl0aGluZyB0aGF0IGluY3JlYXNlcyBpdCIKICAKLSBUb3BvZ3JhcGhpY2FsICAgCgogIC0gJFJ1X2MkIC0gUmVwcmVzZW50ZWQgaGVyZSB1c2luZyB0aGUgInJ1Z2dlZCIgZGF0YSBzZXQgZnJvbSByZXRoaW5raW5nLCBpbiB3aGljaCBhIGNvZWZmIG9mIHJ1Z2dlZG5lc3MgZm9yIGVhY2ggY291bnRyeSB3YXMgYXNzaWduZWQuIFRoaXMgZGF0YSB3YXMgdGFrZW4gZnJvbSBAcmlsZXlUZXJyYWluUnVnZ2VkbmVzc0luZGV4MTk5OQogIAotIFNvaWwgVHlwZSAgCgogIC0gVGhpcyB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGlzIGFuYWx5c2lzLiBBbHRob3VnaCwgaXQgY291bGQgYmUgdXNlZnVsIHRoZXJlIGlzIG5vIGdvb2Qgd2F5IHRvIHF1YW50aWZ5IHNvaWwgdHlwZSBvbiBhIGNvdW50cnkgbGV2ZWwgYmFzaXMuIFRoaXMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgZ3JpZCBjZWxsIG1vZGVsLCBhcyByZWdpb25zIGNhbiBiZSBlYXNpbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSBncmlkIGNlbGwgc3RydWN0dXJlLiAKCi0gV2F0ZXIgU3VwcGx5ICAgIAoKICAtICRSX2MkIC0gVG90YWwgUHJlY2lwaXRhdGlvbiAtICBUcmFuc2xhdGVkIG91dHB1dCBmcm9tIExQSm1MLiBTdW1tZWQgYWNyb3NzIHR3byBkaW1lbnNpb25zOiBtb250aCBhbmQgY291bnRyeS4gSW4gbW0vY291bnRyeS95ZWFyICAKLSBDcm9wIFR5cGUgIAoKICAtIEZyYWN0aW9uIG9mIGVhY2ggY3JvcCBncm93biBwZXIgY291bnRyeSAtICBUcmFuc2xhdGVkIG91dHB1dCBmcm9tIExQSm1MLiBJbmRpdmlkdWFsIGNyb3AgZnJhY3Rpb24gcGVyIGdyaWQgY2VsbCBtdWx0aXBsaWVkIGJ5IHJlc3BlY3RpdmUgZ3JpZCBjZWxsIGFyZWEsIHN1bW1lZCBvbiBhIGNvdW50cnkgbGV2ZWwgZ2l2aW5nIGhhIG9mIGVhY2ggY3JvcCBncm93biBwZXIgY291bnRyeS4gVGhpcyB3YXMgdGhlbiBkaXZpZGVkIGJ5IHRvdGFsIGFyZWEgb2YgdGhlIGNvdW50cnkgdG8gYWNoaWV2ZSB0aGUgJSBhcmVhIG9jY3VwaWVkIGJ5IGEgY2VydGFpbiBjcm9wIHBlciBjb3VudHJ5LiBTdGlsbCB3b3JraW5nIG91dCBob3cgdG8gd29yayB3aXRoIHRoaXMgcHJlZGljdG9yLiAKCi0gU29jaWFsIEluZmx1ZW5jZXMgIAoKICAtICRQX2MkIC0gVG90YWwgUG9wdWxhdGlvbiAtIEVhY2ggY291bnRyeSdzIHRvdGFsIHBvcHVsYXRpb24gb24gYSB5ZWFybHkgYmFzaXMuIFRha2VuIGZyb20gR2FwbWluZGVyLiBBZ2FpbiwgdGhpcyB3aWxsIGJlIGxvZ2dlZCwgZHVlIHRvIHRoZSBzYW1lIGFyZ3VtZW50IGZvciBHRFAsIGFuZCBjZW50ZXJlZC4KICAKQWxsIHZhcmlhYmxlcyB3aWxsIGJlIHNjYWxlZCBvciBjZW50ZXJlZC4gCgoKRmlyc3QsIHRoZSBJU08gY29kZXMgYW5kIFJlZ2lvbnMgdG8gYmUgYWJsZSB0byBob2xkIHNvbWUgc3RydWN0dXJlLiAgCgpgYGB7cn0KI3RoZSBJU08gY29kZXMgYW5kIHJlZ2lvbmFsIGRhdGEgZnJvbSBHYXBtaW5kZXIKaXNvIDwtIHJlYWQuY3N2MigiL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9EYXRhL0dBUG1pbmRlcl9JU09jb2Rlcy5jc3YiKQppc28gPC0gaXNvWywgLWMoMiw3LDEwLDEyLDEzKV0gI3JlbW92aW5nIGV4dHJhIGluZm8KCiNyZW5hbWluZyBzb21lIGNvbHMKaXNvIDwtIAogIGlzbyAlPiUgCiAgcmVuYW1lKElTTyA9IEdFTywgY291bnRyeSA9IG5hbWUpCgojZml4aW5nIHRoZSB2YXJpYWJsZSB0eXBlcwppc28kSVNPIDwtIGFzLmZhY3Rvcihpc28kSVNPKQppc28kY291bnRyeSA8LSBhcy5mYWN0b3IoaXNvJGNvdW50cnkpCmlzbyRmb3VyX3JlZ2lvbnMgPC0gYXMuZmFjdG9yKGlzbyRmb3VyX3JlZ2lvbnMpCmlzbyRlaWdodF9yZWdpb25zIDwtIGFzLmZhY3Rvcihpc28kZWlnaHRfcmVnaW9ucykKaXNvJHNpeF9yZWdpb25zIDwtIGFzLmZhY3Rvcihpc28kc2l4X3JlZ2lvbnMpCmlzbyRzaXhfcmVnaW9ucyA8LSBhcy5mYWN0b3IoaXNvJHNpeF9yZWdpb25zKQppc28kV29ybGQuYmFuay5yZWdpb24gPC0gYXMuZmFjdG9yKGlzbyRXb3JsZC5iYW5rLnJlZ2lvbikKc3RyKGlzbykKCiNwYXN0IG1lIGhlbHBpbmcgZnV0dXJlIG1lCiNmaXhpbmcgTWFjZWRvbmlhLCBGWVIgdG8gTm9ydGggTWFjZWRvbmlhCmlzbyRjb3VudHJ5IDwtIGFzLmNoYXJhY3Rlcihpc28kY291bnRyeSkKaXNvW2lzbyA9PSAiTWFjZWRvbmlhLCBGWVIiXSA8LSAiTm9ydGggTWFjZWRvbmlhIgppc28kY291bnRyeSA8LSBhcy5mYWN0b3IoaXNvJGNvdW50cnkpCmBgYApDb29sLCB3ZSBoYXZlIG11bHRpcGxlIHJlZ2lvbnMgaGVyZSB0aGF0IHdlIGNvdWxkIHVzZSBpbiB0aGUgZnV0dXJlIGZvciBzb21lIG11bHRpbGV2ZWwgYnVzaW5lc3MuIEFsc28sIGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgaXMgaGVyZSwgd2hpY2ggd2UgY2FuIGFsc28gdHJ5IGxhdGVyLiBPYnZpb3VzbHkgdGhlc2UgbGF0IGFuZCBsb24gbWVhc3VyZW1lbnRzIHdpbGwgbWVhbiBub3RoaW5nIGZvciBhIGNvdW50cnkgbGlrZSBDaGluYSBvciB0aGUgVVNBLCBidXQgdGhleSBhcmUgbmljZSB0byBoYXZlLiAgICAKCgojIyBJbmNvbWUKCkluY29tZSBkYXRhIGlzIGNvbWluZyBmcm9tIEdhcG1pbmRlciwgYXMgdGhleSBoYXZlIHB1dCByZWFsIGVmZm9ydCBpbiB0byBmaWxsaW5nIGFsbCB0aGUgZ2FwcyBpbiBpbmNvbWUgYW5kIHBvcHVsYXRpb24gZm9yIHRoZSBsYXN0IDE1MCB5ZWFycy4gSW5jb21lIGlzIGluIHRlcm1zIG9mIHRoZSAyMDExIFVTRCBhbmQgaXMgaW5mbGF0aW9uIGFkanVzdGVkLiAgCgpgYGB7cn0KI2luY29tZSBoZXJlIGlzIDIwMTEgdXNkIAppbmNvbWUgPC0gcmVhZC5jc3YoIi9Wb2x1bWVzL1JhY2hlbEV4dGVybmFsL1RoZXNpcy9UaGVzaXMvRGF0YS9HYXBtaW5kZXJfaW5jb21lX3Blcl9wZXJzb25fZ2RwcGVyY2FwaXRhX3BwcF9pbmZsYXRpb25fYWRqdXN0ZWQuY3N2IikKaW5jb21lIDwtIGluY29tZVssIGMoMSwgMTYyOjIwNyldICNyZW1vdmluZyBleHRyYSB5ZWFycwoKI21ha2luZyBsb25nIGRhdGEKaW5jb21lIDwtIAogIGluY29tZSAlPiUgIAogIHBpdm90X2xvbmdlcighY291bnRyeSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJpbmNvbWUiKSAKCiNzdGlsbCBoYXZlIHRoZSB4cyB0aGVyZQppbmNvbWUkeWVhciA8LSBzdHJfcmVtb3ZlX2FsbChpbmNvbWUkeWVhciwgIltYXSIpCiN0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgdmFyaWFibGUgdHlwZXMKaW5jb21lJHllYXIgPC0gYXMubnVtZXJpYyhpbmNvbWUkeWVhcikKaW5jb21lJGNvdW50cnkgPC0gYXMuZmFjdG9yKGluY29tZSRjb3VudHJ5KQoKI2xvZyBhbmQgc3RhbmRhcmRpemUKaW5jb21lJGxvZ19pbmNvbWUgPC0gbG9nKGluY29tZSRpbmNvbWUpCmluY29tZSA8LSBpbmNvbWUgJT4lIAogIG11dGF0ZShsb2dfaW5jb21lX3N0ZCA9IGxvZ19pbmNvbWUgLyBtZWFuKGxvZ19pbmNvbWUpKQoKI2Egc3VtbWFyeQpzdW1tYXJ5KGluY29tZSkKCiNwYXN0IG1lIGhlbHBpbmcgZnV0dXJlIG1lIGFnYWluCiNmaXhpbmcgRXN3YXRpbmkgdG8gU3dhemlsYW5kIChldmVuIHRob3VnaCBFc3dhdGluaSBpcyB0aGUgY29ycmVjdCBuYW1lKQppbmNvbWUkY291bnRyeSA8LSBhcy5jaGFyYWN0ZXIoaW5jb21lJGNvdW50cnkpCmluY29tZVtpbmNvbWUgPT0gIkVzd2F0aW5pIl0gPC0gIlN3YXppbGFuZCIKaW5jb21lJGNvdW50cnkgPC0gYXMuZmFjdG9yKGluY29tZSRjb3VudHJ5KQoKYGBgCgpMb2dnaW5nIGFuZCBzdGFuZGFyZGl6aW5nIGlzIG5lY2Vzc2FyeSBoZXJlLiBBZ2FpbiwgdGhlIGFyZ3VtZW50IGlzIHRoYXQgd2VhbHRoIGJlZ2V0cyB3ZWFsdGgsIHNvIGluY29tZSBpcyBsb2dhcml0aG1pYy4gRnJvbSB0aGVyZSBqdXN0IGNlbnRlciB0aGUgbWVhbiBhdCAwIHdpdGggYSBzdGRldiBvZiAxIGZvciBzdGFuZGFyZGl6YXRpb24uICAKCgoKIyMgUG9wdWxhdGlvbgoKUG9wdWxhdGlvbiBkYXRhIGlzIGFsc28gdGFrZW4gZnJvbSBHYXBtaW5kZXIuIFRoZSBzYW1lIHByb2Nlc3Mgb2YgbG9nZ2luZyBhbmQgc3RhbmRhcmRpemluZyB3aWxsIGJlIGNhcnJpZWQgb3V0IGhlcmUuIAoKYGBge3J9CiNwb3B1bGF0aW9uIGRhdGEgYWxzbyB0YWtlbiBmcm9tIEdhcG1pbmRlcgpwb3B1bGF0aW9uIDwtIHJlYWQuY3N2KCIvVm9sdW1lcy9SYWNoZWxFeHRlcm5hbC9UaGVzaXMvVGhlc2lzL0RhdGEvR2FwbWluZGVyX3BvcHVsYXRpb25fdG90YWwuY3N2IikKCiNyZW1vdmluZyBleHRyYSB5ZWFycwpwb3B1bGF0aW9uIDwtIHBvcHVsYXRpb25bLCBjKDEsIDE2MjoyMDcpXSAKI21ha2luZyBsb25nZXIgZGF0YQpwb3B1bGF0aW9uIDwtIAogIHBvcHVsYXRpb24gJT4lICAKICBwaXZvdF9sb25nZXIoIWNvdW50cnksIG5hbWVzX3RvID0gInllYXIiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpIAoKI3JlbW92aW5nIHRoZSBYcyBmcm9tIHRoZSB5ZWFyIHN0cmluZ3MKcG9wdWxhdGlvbiR5ZWFyIDwtIHN0cl9yZW1vdmVfYWxsKHBvcHVsYXRpb24keWVhciwgIltYXSIpCgojZml4aW5nIHZhcmlhYmxlIHR5cGVzCnBvcHVsYXRpb24kY291bnRyeSA8LSBhcy5mYWN0b3IocG9wdWxhdGlvbiRjb3VudHJ5KQpwb3B1bGF0aW9uJHllYXIgPC0gYXMubnVtZXJpYyhwb3B1bGF0aW9uJHllYXIpCgojbG9nIGFuZCBzdGFuZGFyZGl6ZSwgc2FtZSBhcmd1bWVudCBhcyBpbmNvbWU6IHBvcHVsYXRpb24gYmVnZXRzIHBvcHVsYXRpb24KcG9wdWxhdGlvbiRsb2dfcG9wIDwtIGxvZyhwb3B1bGF0aW9uJHBvcHVsYXRpb24pCnBvcHVsYXRpb24gPC0gcG9wdWxhdGlvbiAlPiUgCiAgbXV0YXRlKGxvZ19wb3Bfc3RkID0gbG9nX3BvcCAvIG1lYW4obG9nX3BvcCkpCgpzdW1tYXJ5KHBvcHVsYXRpb24pCgojYW5ubmQgYWdhaW4uLi4KI2ZpeGluZyBFc3dhdGluaSB0byBTd2F6aWxhbmQgKGV2ZW4gdGhvdWdoIEVzd2F0aW5pIGlzIHRoZSBjb3JyZWN0IG5hbWUpCnBvcHVsYXRpb24kY291bnRyeSA8LSBhcy5jaGFyYWN0ZXIocG9wdWxhdGlvbiRjb3VudHJ5KQpwb3B1bGF0aW9uW3BvcHVsYXRpb24gPT0gIkVzd2F0aW5pIl0gPC0gIlN3YXppbGFuZCIKcG9wdWxhdGlvbiRjb3VudHJ5IDwtIGFzLmZhY3Rvcihwb3B1bGF0aW9uJGNvdW50cnkpCmBgYAoKU28gc29tZSBpc3N1ZXMgYXJpc2UgaGVyZSB3aXRoIHRoZSBmYWN0IHRoYXQgd2UgaGF2ZSBkaWZmZXJlbnQgY291bnRyeSBkYXRhIGZvciBlYWNoIGRhdGFmcmFtZS4gU29tZXRpbWVzIHRoZSBuYW1lcyBhcmUgY2FwaXRhbGl6ZWQsIG90aGVyIHRpbWVzIHRoZXJlIGFyZSBzcGFjZXMgaW5zdGVhZCBvZiB1bmRlcnNjb3Jlcy4gQnkgdXNpbmcgYGFudGlfam9pbigpYCBJIGNhbiBzZWUgd2hhdCB3b24ndCBiZSBqb2luZWQuIEFsc28gdGhpcyBnb2VzIGJvdGggd2F5cywgYGFudGlfam9pbigpYCByZXR1cm5zIHJvd3Mgb2YgeCB0aGF0IGRvIG5vdCBoYXZlIGEgbWF0Y2ggaW4geS4gIAoKYGBge3J9Cmlzb3BvcCA8LSBhbnRpX2pvaW4oaXNvLCBwb3B1bGF0aW9uLCBieSA9ICJjb3VudHJ5IikKc3VtbWFyeShpc29wb3ApCgpwb3Bpc28gPC0gYW50aV9qb2luKHBvcHVsYXRpb24sIGlzbywgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkocG9waXNvKQpgYGAKCldlbnQgYmFjayB1cCBhbmQgc29sdmVkIHRoZSBpc3N1ZSBvZiBOb3J0aCBNYWNlZG9uaWEgYW5kIFN3YXppbGFuZC4gVGhlcmUgYXJlIHN0aWxsIGlzc3VlcyB3aXRoIEhvbmcgS29uZyBhbmQgVGFpd2FuIGFzIHRoZXkgYXJlIHBhcnQgb2YgQ2hpbmEuIElTTyBoYXMgZGF0YSBmb3IgSG9uZyBLb25nIGFuZCBUYWl3YW4gdGhhdCBwb3B1bGF0aW9uIGRvZXMgbm90IGhhdmUuICBJIHdvbnQgaW5jbHVkZSB0aGVtIGluIHRoZSBIVE1MIGJ1dCB0aGV5IGFyZSBpbiB0aGUgY29kZS4gIAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KaXNvaW5jIDwtIGFudGlfam9pbihpc28sIGluY29tZSwgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkoaXNvaW5jKQoKaW5jaXNvIDwtIGFudGlfam9pbihpbmNvbWUsIGlzbywgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkoaW5jaXNvKQpgYGAKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpwb3BpbmMgPC0gYW50aV9qb2luKHBvcHVsYXRpb24sIGluY29tZSwgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkocG9waW5jKQoKaW5jcG9wIDwtIGFudGlfam9pbihpbmNvbWUsIHBvcHVsYXRpb24sIGJ5ID0gImNvdW50cnkiKQpzdW1tYXJ5KGluY3BvcCkKYGBgCgoKQWxyaWdodCwgc28gSSB3aWxsIGxlZnQgam9pbiBJU08gYW5kIHBvcHVsYXRpb24gdGhlbiBhZ2FpbiB3aXRoIGluY29tZT8gTm90IHN1cmUgdGhhdCB0aGlzIHdpbGwgc29sdmUgbXkgcHJvYmxlbSwgYnV0IGxldHMgdHJ5IGl0LgpgYGB7cn0KI3JlbW92ZSBhbGwgdGhlc2UgcmFuZG8gdGFibGVzCnJtKHBvcGluYywgaW5jaXNvLCBpbmNwb3AsIHBvcGlzbywgaXNvaW5jLCBpc29wb3ApCgojCmlzbyA8LSBsZWZ0X2pvaW4oaXNvLCBwb3B1bGF0aW9uLCBieSA9ICJjb3VudHJ5IikKaXNvIDwtIGxlZnRfam9pbihpc28sIGluY29tZSwgYnkgPSBjKCJjb3VudHJ5IiwgInllYXIiKSkKCiMgYWxyaWdodCAxOTcgY291bnRyaWVzISB3aG9vcCEKc3RyKGlzbykKCnJtKGluY29tZSwgcG9wdWxhdGlvbikKYGBgCgpOb3csIGpvaW4gSVNPIHRvIEFFSSB3aXRoIGEgbWVyZ2UgKGNhdXNlIGluIHRoaXMgY2FzZSB0aGUgZHluYW1pY3Mgb2YgbWVyZ2UgYXJlIGNsZWFyZXIgZm9yIG1lKS4gSG9waW5nIHRvIHByZXNlcnZlIGFsbCBkYXRhISAKCmBgYHtyfQphZWkgPC0gbWVyZ2UoYWVpLCBpc28sIGJ5ID0gYygiSVNPIiwiY291bnRyeSIsICJ5ZWFyIiksIGFsbC54ID0gVFJVRSkKcm0oaXNvKQpzdHIoYWVpKSAKYGBgCgpTb2x2ZWQgdGhlIGlzc3VlLCAyMzIgZmFjdG9ycyBmb3IgYm90aCBjb3VudHJpZXMgYW5kIElTTywgbWVhbmluZyB0aGF0IHdlIGhhdmUgYmVlbiB1c2luZyB0aGUgb3JpZ2luYWwgQUVJIGZpbGUgZnJvbSBTaWViZXJ0IGFzIHRoZSBtYWluIGRhdGEgZnJhbWUgdG8gam9pbiB0by4gR29vZC4gVGhpcyBpcyB0aGUgZGF0YSB0aGF0IG5lZWRzIHRvIGJlIG1haW50YWluZWQsIE5BcyBjYW4gcG9wIHVwIGluIG90aGVyIGNvbHMgYnV0IG5vdCBpcnJpZ2F0ZWQgYXJlYS4gICAKCkJ1dCBJIHN0aWxsIHdvdWxkIGxpa2UgdG90YWwgR0RQIGZvciBsYXRlciBzbyBsZXRzIHRyYW5zZm9ybSB1c2luZyBwb3B1bGF0aW9uLiAKYGBge3J9CmFlaSRpbmNvbWUgPC0gYXMubnVtZXJpYyhhZWkkaW5jb21lKSAKCiNtdXRhdGluZyBmb3IgdG90YWwgR0RQIGFuZCBsb2cgR0RQCmFlaSA8LQogIGFlaSAlPiUKICBtdXRhdGUoR0RQdG90ID0gaW5jb21lKnBvcHVsYXRpb24pICU+JQogIG11dGF0ZShsb2dfZ2RwX3RvdCA9IGxvZyhHRFB0b3QpKSAKCiNjcmVhdGluZyB0aGUgZGYgdG8gc3RhbmRhcmRpemUgd2l0aG91dCB0aGUgTkFzCmFlaTIgPC0KICBhZWkgJT4lIAogIHNlbGVjdChJU08sIHllYXIsIGxvZ19nZHBfdG90KSAlPiUKICBuYS5vbWl0KCkgJT4lIAogIG11dGF0ZShsb2dfZ2RwX3RvdF9zdGQgPSBsb2dfZ2RwX3RvdC9tZWFuKGxvZ19nZHBfdG90KSkgJT4lIAogIHNlbGVjdChJU08sIHllYXIsIGxvZ19nZHBfdG90X3N0ZCkKCiNub3cgcmVqb2luIQphZWkgPC0gCiAgbGVmdF9qb2luKGFlaSwgYWVpMiwgYnkgPSBjKCJJU08iLCAieWVhciIpKQoKc3RyKGFlaSkKYGBgCgoKRmluYWxseSwgbGV0cyBjaGVjayBvdXQgYSBxdWljayBoaXN0b2dyYW0gb2YgR0RQIGFuZCBwb3AsCmBgYHtyfQpoaXN0KGFlaSRsb2dfZ2RwX3RvdF9zdGQsIGJyZWFrcyA9IDEwMCkKYGBgCgpgYGB7cn0KaGlzdChhZWkkbG9nX3BvcF9zdGQsIGJyZWFrcyA9IDEwMCkKYGBgCgoKIyMgRGVhbGluZyB3aXRoIFNvbWUgSXNzdWVzCgpUaGVyZSBhcmUgYSBsb3Qgb2YgY291bnRyaWVzIHRoYXQgaGF2ZSBubyBkYXRhIGZvciB0aGUgcmVnaW9ucywgYnV0IGhhdmUgbm9uIHplcm8gaXJycGVyYy9mcmFjIHdoaWNoIEkgd2lsbCB1c2UgaW4gZnVydGhlciBhbmFseXNpcywgc28gd2UgbmVlZCB0byByZXBsYWNlIHRoZSByZWdpb25zLiAKCmBgYHtyfQojdmlldyB3aGljaCBjb3VudHJpZXMgZG9uJ3QgaGF2ZSByZWdpb25zIGJ1dCBoYXZlIG5vbiB6ZXJvIGlycnByZWMKbmFfcmVnaW9ucyA8LSBhZWlbaXMubmEoYWVpJGZvdXJfcmVnaW9ucyksXQoKI0FydWJhCmFlaSA8LSBhZWkgJT4lCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhX25vcnRoJykpICU+JQojYW1lcmljYW4gc2Ftb2EKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdBU00nLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQVNNJywgJ2Vhc3RfYXNpYV9wYWNpZmljJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnQVNNJywgJ2Vhc3RfYXNpYV9wYWNpZmljJykpICU+JQojYmVybXVkYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0JNVScsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQk1VJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdCTVUnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUgCiNjb3RlIGQnaXZvaXJlCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnQ0lWJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQ0lWJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0NJVicsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lIAojZGVtb2NyYXRpYyByZXB1YmxpYyBvZiBjb25nbwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0NPRCcsICdhZnJpY2EnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0NPRCcsICdzdWJfc2FoYXJhbl9hZnJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdDT0QnLCAnYWZyaWNhX3N1Yl9zYWhhcmFuJykpICU+JSAKI3JlcHVibGljIG9mIGNvbmdvCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnQ09HJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQ09HJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0NPRycsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lIAojY2F5bWFuIGlzbGFuZHMKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdDWU0nLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0NZTScsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnQ1lNJywgJ2FtZXJpY2Ffbm9ydGgnKSkgJT4lCiNGYXJvZSBpc2xhbmRzCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnRlJPJywgJ2V1cm9wZScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnRlJPJywgJ2V1cm9wZV9jZW50cmFsX2FzaWEnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdGUk8nLCAnZXVyb3BlX3dlc3QnKSkgJT4lCiNtaWNyb25lc2lhCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnRlNNJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0ZTTScsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0ZTTScsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI2dpYnJhbHRhcgogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dJQicsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dJQicsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR0lCJywgJ2V1cm9wZV93ZXN0JykpICU+JQojR3VhZGVsb3VwZQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dMUCcsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnR0xQJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdHTFAnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUKI2dyZWVubGFuZAogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dSTCcsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dSTCcsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR1JMJywgJ2V1cm9wZV93ZXN0JykpICU+JQojZnJlbmNoIEd1aWFuYSAKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdHVUYnLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dVRicsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR1VGJywgJ2FtZXJpY2Ffc291dGgnKSkgJT4lCiNndWFtCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnR1VNJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dVTScsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0dVTScsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI0t5cmd5enN0YW4KICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdLR1onLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnS0daJywgJ2V1cm9wZV9jZW50cmFsX2FzaWEnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdLR1onLCAnYXNpYV93ZXN0JykpICU+JQojbGFvcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0xBTycsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdMQU8nLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdMQU8nLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNNYWNlZG9uaWEKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdNS0QnLCAnZXVyb3BlJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdNS0QnLCAnZXVyb3BlX2NlbnRyYWxfYXNpYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ01LRCcsICdldXJvcGVfZWFzdCcpKSAlPiUKI01hcnRpbmlxdWUgCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnTVRRJywgJ2FtZXJpY2FzJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdNVFEnLCAnYW1lcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ01UUScsICdhbWVyaWNhX25vcnRoJykpICU+JQojbmV3IGNhbGVkb25pYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ05DTCcsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdOQ0wnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdOQ0wnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNwdWVydG8gcmljbwogbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUFJJJywgJ2FtZXJpY2FzJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdQUkknLCAnYW1lcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1BSSScsICdhbWVyaWNhX25vcnRoJykpICU+JQojUGFsZXN0aW5lIChXZXN0IEJhbmsgKyBHYXphIHN0cmlwKQogbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUFNFJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1BTRScsICdtaWRkbGVfZWFzdF9ub3J0aF9hZnJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdQU0UnLCAnYXNpYV93ZXN0JykpICU+JQojZnJlbmNoIFBvbHluZXNpYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1BZRicsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdQWUYnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdQWUYnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNSZXVuaW9uCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUkVVJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnUkVVJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1JFVScsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lCiNTZXJiaWEsIE1vbnRlbmVncm8sIEtvc292bwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1NNSycsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1NNSycsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnU01LJywgJ2V1cm9wZV9lYXN0JykpICU+JQojU2xvdmFraWEKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdTVksnLCAnZXVyb3BlJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdTVksnLCAnZXVyb3BlX2NlbnRyYWxfYXNpYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1NWSycsICdldXJvcGVfZWFzdCcpKSAlPiUKI1R1cmtzIGFuZCBDYWljb3MgSXNsYW5kcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1RDQScsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVENBJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdUQ0EnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUKI0Vhc3QgVGltb3IKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdUTFMnLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVExTJywgJ2Vhc3RfYXNpYV9wYWNpZmljJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnVExTJywgJ2Vhc3RfYXNpYV9wYWNpZmljJykpICU+JQojdGFpd2FuCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnVFdOJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1RXTicsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1RXTicsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI0JyaXRpc2ggdmlyZ2luIElzbGFuZHMKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdWR0InLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1ZHQicsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnVkdCJywgJ2FtZXJpY2Ffbm9ydGgnKSkgJT4lCiNVUyBWaXJnaW4gSXNsYW5kcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1ZJUicsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVklSJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsIElTTyA9PSAnVklSJywgJ2FtZXJpY2Ffbm9ydGgnKSkgCgpgYGAKTmV4dCB0aW1lIEknbGwgd3JpdGUgYSBmdW5jdGlvbi4KClRoZXJlIGFyZSBhbHNvIGEgbG90IG9mIGNvdW50cmllcyB0aGF0IGhhdmUgTkEgdmFsdWVzIGZvciB0aGVpciBpbmNvbWUgb3IgcG9wdWxhdGlvbi4gVGFrZSBhIHBlZWsgaGVyZS4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxvdGFuYXMgPC0gIGFlaVtyb3dTdW1zKGlzLm5hKGFlaSkpID4gMCxdCmxvdGFuYXMgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBzZWxlY3QoaW5jb21lLCBwb3B1bGF0aW9uKSAlPiUgIAogIHN1bW1hcmlzZV9hbGwoZnVucyhzdW0oaXMubmEoLikpKSkKCgpgYGAKCgpUaGUgY291bnRyaWVzIHRoYXQgZG9uJ3QgaGF2ZSBpbmNvbWUgYWxzbyBkb24ndCBoYXZlIHBvcHVsYXRpb24sIHNvIGFzIGxlYXN0IEkgYW0gY29uc2lzdGVudCBpbiBteSBtaXNzaW5nIGRhdGEuIEkgaGF2ZSB0byBtb3ZlIG9uIHNvIEkgd2lsbCBqdXN0IGxlYXZlIHRoaXMgaGVyZSBmb3IgYSBtaW51dGUuIFBlcmhhcHMgbGF0ZXIgd2Ugc2hvdWxkIGZpbGwgdGhlc2UgdmFyaWFibGVzLiAgCgoKCiMjIFByZWNpcGl0YXRpb24KCkFnYWluLCBwcmVjaXBpdGF0aW9uIGlzIHRyYW5zbGF0ZWQgb3V0cHV0IGZyb20gTFBKbUwuIFByZWNpcGl0YXRpb24gd2FzIGNob3NlbiBiZWNhdXNlIGl0IGNvdWxkIGJlIHN1bW1lZCBhY3Jvc3MgY291bnRyaWVzLCBhcyBvdGhlciBkYXRhIGNvdWxkIG5vdCAobGlrZSBkaXNjaGFyZ2Ugb3IgRVQpLiBJIGhhdmUgc3VtbWVkIHRoZSBwcmVjaXBpdGF0aW9uIGJ5IGNvdW50cnkgYW5kIHllYXIuIEkgYW0gbm90IHN1cmUgd2hldGhlciBJIHNob3VsZCBzY2FsZSBvciBzdGFuZGFyZGl6ZSBwcmVjaXAsIEkgd2lsbCBkbyBhbGwgdGhlIHBvc3NpYmxlIGNvbWJpbmF0aW9ucyBhdCB0aGUgbW9tZW50LiAKYGBge3IgUHJlY2lwIE1hbmlwdWxhdGlvbiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI3ByZWNpcGl0YXRpb24KI2NmdGFuZHByZWNpcCBpcyBhIHNjcmlwdCB3aXRoIGFsbCB0aGUgZ3JpZCBjZWxsIHZhbHVlcy4gCmNmdGFuZHByZWNpcCA8LSByZWFkLmNzdignL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9EYXRhL2NmdF9hbmRfcHJlY2lwZGF0YS5jc3YnKQpjZnRhbmRwcmVjaXAkSVNPIDwtIGFzLmZhY3RvcihjZnRhbmRwcmVjaXAkSVNPKQpjZnRhbmRwcmVjaXAgPC0gY2Z0YW5kcHJlY2lwWywgLWMoMSldICNyZW1vdmUgaWQgY29sCmNmdGFuZHByZWNpcCA8LSBzdWJzZXQoY2Z0YW5kcHJlY2lwLCB5ZWFyID49IDE5NjApCgojbG9nIGFuZCBzY2FsZQpwcmVjaXAgPC0gCiAgY2Z0YW5kcHJlY2lwICU+JSAKICBzZWxlY3QoSVNPLCB5ZWFyLCBwcmVjaXBtbSkgJT4lIAogIGdyb3VwX2J5KElTTywgeWVhcikgJT4lIAogIHN1bW1hcmlzZShwcmVjaXB0b3QgPSAoc3VtKHByZWNpcG1tKSkpICU+JSAjc3VtIGdyaWQgY2VsbHMgYnkgSVNPIGFuZCB5ZWFyCiAgbXV0YXRlKHByZWNpcF9zYyA9IHByZWNpcHRvdC9tYXgocHJlY2lwdG90KSkgJT4lIAogIG11dGF0ZShwcmVjaXBfc3RkID0gcHJlY2lwdG90L21lYW4ocHJlY2lwdG90KSkgJT4lIAogIG11dGF0ZShsb2dfcHJlY2lwID0gbG9nKHByZWNpcHRvdCsxKSkgJT4lICMxIGlzIGFkZGVkIGhlcmUgdG8gcHJldmVudCAtSW5mCiAgbXV0YXRlKGxvZ19wcmVjaXBfc2MgPSBsb2dfcHJlY2lwL21heChsb2dfcHJlY2lwKSkgJT4lIAogIG11dGF0ZShsb2dfcHJlY2lwX3N0ZCA9IGxvZ19wcmVjaXAvbWVhbihsb2dfcHJlY2lwKSkKCiNtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBwcmVjaXAsIGJ5ID0gYygiSVNPIiwgInllYXIiKSwgYWxsLnggPSBUUlVFKQpybShwcmVjaXApCmBgYAoKQW5kIHNvbWUgaGlzdG9ncmFtcyB0byBjaGVjayBvdXQgdGhlIHNjYWxlZC9zdGFuZGFyZGl6ZWQgZGF0YS4gCmBgYHtyIFByZWNpcCBIaXN0c30KaGlzdChhZWkkcHJlY2lwdG90LCBicmVha3MgPSAxMDApCmhpc3QoYWVpJHByZWNpcF9zYywgYnJlYWtzID0gMTAwKQpoaXN0KGFlaSRwcmVjaXBfc3RkLCBicmVha3MgPSAxMDApCmhpc3QoYWVpJGxvZ19wcmVjaXAsIGJyZWFrcyA9IDEwMCkKaGlzdChhZWkkbG9nX3ByZWNpcF9zYywgYnJlYWtzID0gMTAwKQpoaXN0KGFlaSRsb2dfcHJlY2lwX3N0ZCwgYnJlYWtzID0gMTAwKQpgYGAKCgojIyBDcm9wIEZyYWN0aW9uCgpVZmYuIFRoZW4gY29tZXMgY3JvcCBmcmFjdGlvbi4gQXMgbWVudGlvbmVkIGFib3ZlIGluZGl2aWR1YWwgY3JvcCBmcmFjdGlvbiBwZXIgZ3JpZCBjZWxsIGlzIG11bHRpcGxpZWQgYnkgcmVzcGVjdGl2ZSBncmlkIGNlbGwgYXJlYSwgc3VtbWVkIG9uIGEgY291bnRyeSBsZXZlbCBnaXZpbmcgaGEgb2YgZWFjaCBjcm9wIGdyb3duIHBlciBjb3VudHJ5LiBUaGlzIHdhcyB0aGVuIGRpdmlkZWQgYnkgdG90YWwgYXJlYSBvZiB0aGUgY291bnRyeSB0byBhY2hpZXZlIHRoZSAlIGFyZWEgb2NjdXBpZWQgYnkgYSBjZXJ0YWluIGNyb3AgcGVyIGNvdW50cnkuCmBgYHtyIENGVCBtYW5pcHVsYXRpb24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNwdWxsIGNmdCBmcmFjIG91dHRhIGhlcmUKY2Z0IDwtIAogIGNmdGFuZHByZWNpcCAlPiUgCiAgc2VsZWN0KC1jKDQpKSAlPiUgI3JlbW92aW5nIHByZWNpcAogIG11dGF0ZV9lYWNoKGZ1bnMoLipjZWxsYXJlYW0yKSwgYyg0OjM1KSkgJT4lICNtdWx0aXBseSBhbGwgZnJhY3Rpb25zIHdpdGggdGhlIGNlbGwgYXJlYQogIGdyb3VwX2J5KElTTywgeWVhcikgJT4lICNncm91cCBpbiB0byBjb3VudHJ5IGFuZCB5ZWFyCiAgc3VtbWFyaXNlX2VhY2goZnVucyhzdW0pKSAlPiUgI3Rha2UgY29sIHN1bXMgZm9yIGVhY2ggY3JvcAogIG11dGF0ZShhY3Jvc3MoYygzOjM0KSwgLmZucyA9IH4uL2NlbGxhcmVhbTIpKSAjZGl2aWRlIGNvbCBzdW1zIGJ5IHRvdGFsIGNvdW50cnkgYXJlYSAKCiNyZW1vdmluZyBjYXRlZ29yaWVzIHdpdGggMCAodGhlIGJpb2Z1ZWxzIGFuZCBzdWNoKQpjZnQgPC0gY2Z0WywgLWMoMTgsIDE5LCAyNiwgMzQsIDM1KV0KCiNhbmQgYSBtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBjZnQsIGJ5ID0gYygiSVNPIiwgInllYXIiKSwgYWxsLnggPSBUUlVFKQpybShjZnQsIGNmdGFuZHByZWNpcCkKYGBgCgpJZGsgaG93IHRvIHNob3cgdGhlIGRhdGEgaGVyZS4gQW55IGlkZWFzIG9uIHJlcHJlc2VudGF0aW9uIHdvdWxkIGJlIGhlbHBmdWwgaGVyZS4gCgojIyBUb3BvZ3JhcGhpY2FsCgpUb3BvZ3JhcGhpY2FsIGRhdGEgaXMgcmVwcmVzZW50ZWQgaGVyZSBieSB0aGUgZGF0YSBzZXQgZnJvbSBAcmlsZXlUZXJyYWluUnVnZ2VkbmVzc0luZGV4MTk5OSBhbmQgaXMgY29udmllbnRseSBhdmFpbGFibGUgdGhyb3VnaCB0aGUgYGxpYnJhcnkocmV0aGlua2luZylgIGZyb20gQG1jZWxyZWF0aFN0YXRpc3RpY2FsUmV0aGlua2luZ0JheWVzaWFuMjAxNS4gSXQgcHJvdmlkZXMgYSBydWdnZWRuZXNzIGZhY3RvciBmb3IgZWFjaCBjb3VudHJ5LiAKCmBgYHtyfQojcnVnZ2VkCmRhdGEoInJ1Z2dlZCIpCnJ1ZyA8LSBydWdnZWQgJT4lIHNlbGVjdChjKCJpc29jb2RlIiwgInJ1Z2dlZCIpKSAKY29sbmFtZXMocnVnKSA8LSBjKCJJU08iLCAicnVnZ2VkIikKI3NjYWxpbmcKcnVnJHJ1Z2dlZF9zYyA8LSBydWckcnVnZ2VkIC8gbWF4KHJ1ZyRydWdnZWQpCiNtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBydWcsIGJ5ID0gIklTTyIsIGFsbC54ID0gVFJVRSkKcm0ocnVnLCBydWdnZWQpCgoKYGBgCgpgYGB7cn0KaGlzdChhZWkkcnVnZ2VkX3NjLCBicmVha3MgPSAxMDApCmBgYAoKCioqKiAgIAoKCgojIFRpbWUgU2VyaWVzIEV2b2x1dGlvbiBvZiBDb3VudHJ5IExldmVsIFRhcmdldCBWYXJpYWJsZQoKT2ssIHNvIGxldHMgcGVlayBhdCBob3cgdGhpbmdzIGNoYW5nZSBvdmVyIHRpbWUuIEhlcmUgaXMgYSBncmFwaCBvZiBwZXJjZW50YWdlIG9mIGNvdW50cnkgYXJlYSBlcXVpcHBlZCBmb3IgaXJyaWdhdGlvbiBmcm9tIDE5NjAgLSAyMDA1LgoKYGBge3IgSXJyaWdhdGVkIFRvdGFscyBHcmFwaCwgd2FybmluZz1GQUxTRX0KCnBpcnJmcmFjIDwtCiAgZ2dwbG90KGRhdGEgPSBzdWJzZXQoYWVpLCAhaXMubmEoaXJycGVyYykpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGdyb3VwID0gY291bnRyeSwgY29sb3IgPSBzaXhfcmVnaW9ucykpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyZnJhYykKCgpgYGAKQWx0aG91Z2ggdGhpcyBncmFwaCBoYXMgYSBsb3Qgb2YgY291bnRyaWVzIGFuZCBjYW4gZ2V0IHF1aXRlIG1lc3N5LCBzb21lIGdlbmVyYWwgdHJlbmRzIGFwcGVhci4gU291dGggQXNpYW4gY291bnRyaWVzIHNlZW0gdG8gaGF2ZSBoaWdoIHBlcmNlbnRhZ2VzIG9mIGlycmlnYXRlZCBhcmVhIHBlciB0b3RhbCBsYW5kIGFyZWEgKGlycmlnYXRpb24gcGVyY2VudGFnZSkuIFRoZW4gc2VlbWluZ2x5IGZvbGxvd2VkIGJ5IEVhc3QgQXNpYW4gYW5kIEV1cm9wZWFuIGNvdW50cmllcy4gQWZyaWNhIGFuZCB0aGUgTWlkZGxlIEVhc3QgZG8gbm90IHNlZW0gdG8gYmUgaXJyaWdhdGVkIGFzIG11Y2guIEJlIGF3YXJlIHRoYXQgeW91IGNhbiB0aGVzZSBncmFwaHMgYXJlIGludGVyYWN0aXZlLCB5b3UgbWF5IHpvb20sIHBhbiBvciBjbGljayBvbiB0aGUgbGVnZW5kIHRvIGlzb2xhdGUgdGhlIHJlZ2lvbnMuIEFsdGhvdWdoLCBhIHJlZ2lvbmFsIGJyZWFrZG93biBmb2xsb3dzLgoKCgojIyBTdWItU2FoYXJhbiBBZnJpY2EKICAKYGBge3IgQWZyaWNhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJzc0FGIDwtCiAgZ2dwbG90KGRhdGEgPSBzdWJzZXQoYWVpLCBzaXhfcmVnaW9ucyA9PSAic3ViX3NhaGFyYW5fYWZyaWNhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJzc0FGKQpgYGAKICAKSW4gZ2VuZXJhbCwgQWZyaWNhIGhhcyBsb3cgbGV2ZWxzIG9mIGlycmlnYXRlZCBhcmVhLiBTd2F6aWxhbmQsIFNhbyBUb21lIGFuZCBQcmluY2lwZSwgUmV1bmlvbiBhbmQgTWF1cml0aXVzIGxlYWQgaGVyZSB3aXRoIG1ham9yaXR5IG9mIG90aGVycyBmYWxsaW5nIGJlbG93IHRoZSBsZXZlbHMgb2YgdGhlc2UgY291bnRyaWVzLgoKIyMgRXVyb3BlIGFuZCBDZW50cnRhbCBBc2lhCiAgCmBgYHtyIEV1cm9wZSBJcnJpZ2F0ZWQgVG90YWxzIEdyYXBoLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwaXJyRVUgPC0KICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJldXJvcGVfY2VudHJhbF9hc2lhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJFVSkKYGBgCiAgCkV1cm9wZSBjb250YWlucyBzb21lIGNvdW50cmllcyB0aGF0IHJlYWNoIGhpZ2hlciBwZXJjZW50YWdlcyBvZiBpcnJpZ2F0ZWQgYXJlYS4gQ291bnRyaWVzIHN1Y2ggYXMgdGhlIE5ldGhlcmxhbmRzLCBSb21hbmlhLCBBbGJhbmlhLCBhbmQgQXplcmJhaWphbiBoYXZlIHJlYWNoZWQgcGVha3MgaW4gdGhlIHBhc3QgKHJvdWdobHkgMTAtMTUlIGlycmlnYXRlZCBhcmVhKSBidXQgc2VlbSB0byBiZSBpbiBhIGRlY2xpbmUgdG93YXJkcyB0aGUgZW5kIG91ciBzdHVkeSBwZXJpb2QuIE90aGVyIGNvdW50cmllcyBzdWNoIGFzIEl0YWx5IGFuZCBEZW5tYXJrIGhhdmUgaGFkIG1vcmUgc3RhYmxlIHJpc2VzIHdpdGggbGVzcyBkb3duIHR1cm4gdG93YXJkLiBVbmV4cGVjdGVkbHksIFJ1c3NpYSBoYXMgYSB2ZXJ5IGxvdyBwZXJjZW50YWdlIG9mIGlycmlnYXRlZCBhcmVhLCBob3dldmVyIGF0IHRoaXMgcG9pbnQsIHRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgZWl0aGVyIFJ1c3NpYSdzIGVub3Jtb3VzIHNpemUgY2FuY2VscyBvdXQgaXRzIGlycmlnYXRlZCBhcmVhLCBvciB0aGF0IFJ1c3NpYSByZWNlaXZlcyBlbm91Z2ggcHJlY2lwaXRhdGlvbiBmb3IgdGhlIGNyb3BzIGl0IGdyb3dzIHRoYXQgaXJyaWdhdGlvbiBpcyBub3QgbmVjZXNzYXJ5LiBGdXJ0aGVyIGFuYWx5c2lzIHNob3VsZCByZXZlYWwgdGhpcy4gIAoKIyMgQW1lcmljYXMKCmBgYHtyIEFtZXJpY2FzIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJBTSA8LQogIGdncGxvdChkYXRhID0gc3Vic2V0KGFlaSwgc2l4X3JlZ2lvbnMgPT0gImFtZXJpY2EiKSwgCiAgICAgICAgIG1hcHBpbmcgPSBhZXMoeD15ZWFyLCB5PSBpcnJwZXJjLCBjb2xvciA9IGNvdW50cnkpKSArCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX3hfY29udGludW91cygpICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKSAKCiNydW4gdGhpcyBzZXBhcmF0ZWx5LCBvdGhlcndpc2UgdGhlIHBsb3RseSBwYXJ0IGRvZXNuJ3Qgd29yay4KZ2dwbG90bHkocGlyckFNKQpgYGAKICAKSW4gdGhlIEFtZXJpY2FzLCB0aGUgJSBvZiBhcmVhIGlycmlnYXRlZCBieSBjb3VudHJpZXMgaXMgbG93ZXIgdGhhbiBBc2lhIG9yIEV1cm9wZS4gUGVha3MgaGVyZSBhcmUgQ3ViYSBhbmQgdGhlIERvbWluaWNhbiBSZXB1YmxpYyBhdCBhcm91bmQgcm91Z2hseSA2LTglIG9mIHRoZWlyIHRvdGFsIGNvdW50cmllcyBiZWluZyBpcnJpZ2F0ZWQuIFRoZXJlIGFyZSBzb21lIGlzbGFuZHMgKEJhcmJhZG9zIGFuZCBTdC4gTHVjaWEpIHRoYXQgaGF2ZSBzaGFycCBpbmNyZWFzZXMgaW4gaXJyaWdhdGlvbiBmcmFjdGlvbiwgYnV0IHRoaXMgY291bGQgYmUgYmVjYXVzZSB0aGV5IGFyZSBpc2xhbmRzIGFuZCBhbnkgaXJyaWdhdGlvbiBhdCBhbGwgd291bGQgaW5kdWNlIHRoZSByYXRpb24gb2YgaXJyaWdhdGVkIGxhbmQgdG8gdG90YWwgbGFuZCBzcGlrZS4gQ291bnRpZXMgdGhhdCBoYXZlIGV4cGVyaWVuY2VkIGEgc3RlYWR5IGluY3JlYXNlLCBidXQgYXJlIG5vdCB0aGUgbGVhZGVycyBpbiBvdmVyYWxsIGlycmlnYXRpb24gZnJhY3Rpb24gYXJlIGNvdW50cmllcyB0aGF0IGFyZSBiaWcgYW5kIHByb2R1Y2UgYSBsb3Qgb2YgcHJvZHVjZSAoVVNBLCBNZXhpY28sIENoaWxlKSBUaGUgZ2VuZXJhbCB0cmVuZHMgb2YgaXJyaWdhdGlvbiBpbmNyZWFzZSBzZWVtIHRvIGJlIHVwd2FyZCB3aXRoIHBlcmhhcHMgYSBzbGlnaHQgbGV2ZWxpbmcgb2ZmIHRvd2FyZCB0aGUgZW5kIG9mIHRoZSBzdHVkeSBwZXJpb2QgKGZvciBzb21lIGNvdW50cmllcykgYnV0IGxhY2tpbmcgdGhlIGRpc3RpbmN0IGRvd250dXJuIHRoYXQgaXMgc2VlbiBpbiBFdXJvcGUuICAgCiAgCiMjIEVhc3QgQXNpYSBhbmQgT2NlYW5pYQoKYGBge3IgRWFzdCBBc2lhIGFuZCBPY2VhbmlhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJFQXNpYSA8LSAKICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJlYXN0X2FzaWFfcGFjaWZpYyIpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyRUFzaWEpCmBgYAogIApUaGUgRWFzdCBBc2lhbiBjb3VudHJpZXMgYXJlIHF1aXRlIGhpZ2ggaW4gJSBvZiBpcnJpZ2F0ZWQgYXJlYSwgd2hlbiBjb21wYXJlZCB0byB0aGUgQW1lcmljYXMgb3IgQWZyaWNhLiBUaGUgZm91ciBjb3VudHJpZXMgdGhhdCByZWFjaCB1cHdhcmRzIG9mIChyb3VnaGx5KSAxMCUgb3IgbW9yZSBvZiB0aGVpciB0b3RhbCBhcmVhIGlycmlnYXRlZCB0b3dhcmQgdGhlIGVuZCBvZiB0aGUgc3R1ZHkgcGVyaW9kIGFyZSBWaWV0bmFtLCBOb3J0aCBLb3JlYSwgU291dGggS29yZWEsIGFuZCBUaGFpbGFuZC4gT3RoZXIgY291bnRyaWVzIHRoYXQgaGF2ZSBoaWdoIGlycmZyYWNzIGFyZSBDaGluYSwgSmFwYW4gYW5kIHRoZSBQaGlsaXBwaW5lcy4gSXQgaXMgZXhwZWN0ZWQgdGhhdCBmb3IgdGhpcyByZWdpb24gdGhlIGlycmlnYXRpb24gZnJhY3Rpb24gd291bGQgYmUgaGlnaCBkdWUgdG8gdGhlIGFtb3VudCBvZiByaWNlIHByb2R1Y2VkLiAKCk9jZWFuaWEsIGR1ZSB0byBpdHMgbGFyZ2UgYW1vdW50IG9mIGlzbGFuZHMsIGRvZXMgbm90IGhhdmUgYSBsb3Qgb2YgaXJyaWdhdGlvbiwgbWFqb3JpdHkgb2YgY291bnRyaWVzIGhhdmUgMCUgaXJyaWdhdGlvbi4gTmV3IFplYWxhbmQgKGFyb3VuZCAyJSkgYW5kIEF1c3RyYWxpYSAobGVzcyB0aGFuIDElKSBoYXZlIHNvbWUgaXJyaWdhdGlvbi4gQWx0aG91Z2ggdGhpcyBjb3VsZCBoYXZlIGEgbXVsdGl0dWRlIG9mIHJlYXNvbnMgd2h5IGlycmlnYXRpb24gaXMgc28gbG93IGhlcmUsIHJlZ2FyZGxlc3Mgb2YgdGhlIGZhY3QgdGhhdCBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kIGFyZSB2ZXJ5IHBvcHVsb3VzIGNvdW50cmllcyB3aXRoIG1vdXRocyB0byBmZWVkLiBBdXN0cmFsaWEgaXMgdmVyeSBsYXJnZSBhbmQgcGVyaGFwcyBpdHMgZW5vcm1pdHkgY2FuY2VscyBvdXQgdGhlIGlycmlnYXRlZCBsYW5kIGl0IGRvZXMgaGF2ZS4gCiAgCiMjIFNvdXRoIEFzaWEKYGBge3IgU291dGggQXNpYSBJcnJpZ2F0ZWQgVG90YWxzIEdyYXBoLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwaXJyU0FzaWEgPC0KICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJzb3V0aF9hc2lhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJTQXNpYSkKYGBgClZlcnkgZmV3IGNvdW50cmllcyBoZXJlLCBjb3VudHJpZXMgaW4gdGhpcyBhcmVhIGFyZSBsYXJnZS4gVmVyeSBoaWdoIGxldmVscyBvZiBpcnJpZ2F0aW9uIGhlcmUgY29taW5nIGZyb20gbW9zdCBjb3VudHJpZXMuIEJhbmdsYWRlc2gsIFBha2lzdGFuLCBhbmQgSW5kaWEgYXJlIGhlYXZpbHkgaXJyaWdhdGVkIGNvbXBhcmVkIHRvIHRoZWlyIGxhbmQgYXJlYS4gCgoKIyMgTWlkZGxlIEVhc3QgYW5kIE5vcnRoIEFmcmljYQpgYGB7ciBNaWRkbGUgRWFzdCBhbmQgTm9ydGggQWZyaWNhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJNRSA8LQogIGdncGxvdChkYXRhID0gc3Vic2V0KGFlaSwgc2l4X3JlZ2lvbnMgPT0gIm1pZGRsZV9lYXN0X25vcnRoX2FmcmljYSIpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyTUUpCmBgYAoKSXJyaWdhdGlvbiBpcyBhbHNvIHByZXZhbGVudCBoZXJlIChidXQgbm90IGFzIG11Y2ggYXMgaW4gc291dGggQXNpYSkuIFRoZXNlIGNvdW50cmllcyBhcmUgZHJ5IGFuZCB0aGVyZWZvcmUgd291bGQgbmVlZCBpcnJpZ2F0aW9uIHRvIGhhdmUgZG9tZXN0aWMgZm9vZCBzdXBwbGllcy4gTGViYW5vbiwgSXJhcSBhbmQgSXNyYWVsIGxlYWQgaGVyZS4gT2lsIHByb2R1Y2luZyBjb3VudHJpZXMgaGF2ZSBsaXR0bGUgaXJyaWdhdGlvbiwgdGhleSBhcmUgZHJ5IGFuZCB0aGVpciBHRFAgaXMgaGlnaCwgcGVyaGFwcyBpbXBvcnRhdGlvbiBpcyB0aGUgZWFzaWVzdCBvcHRpb24gZm9yIHRoZW0/CgoqKioKCk92ZXJhbGwsIHRoaXMgbWlnaHQgYmUgYSBnb29kIG92ZXJ2aWV3IG9mIHdoYXQgaXJycGVyYyBsb29rcyBsaWtlIGZvciBlYWNoIHJlZ2lvbi4gCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9VFJVRX0KCnRoZW1lX3NldCh0aGVtZV9taW5pbWFsKCkpCgpnZ3Bsb3Qoc3Vic2V0KGFlaSwgIWlzLm5hKGlycnBlcmMpKSwKICAgICAgIGFlcyh4PXNpeF9yZWdpb25zLCB5PWlycnBlcmMsIGZpbGw9c2l4X3JlZ2lvbnMpKSArIAogIGdlb21fYm94cGxvdChzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyAKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgoqKiogCgojIFJlZmVyZW5jZXMK